Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

เชี่ยวชาญ Ruby Time และ Date Classes: คู่มือครอบคลุม

Time เป็น class ใน Ruby represent จุดเวลาเฉพาะ อ่านบทความนี้จบ จะรู้ทุกอย่างเป็น Ruby time wizard!

Topics covered:

  • แปลง strings เป็น time objects
  • แยก time เป็น components (day/hours/milliseconds...)
  • ใช้ class Date, DateTime และ Time ใน Ruby
  • Format time 任何你想要的方式
  • หาความต่างระหว่าง 2 Time objects

มาเริ่มกัน!

The Ruby Time Class

ใช้ Time class represent เวลาและวันที่ Date มี 3 components:

  • day
  • month
  • year

และ Time:

  • hours
  • minutes
  • seconds

ข้อมูลเก็บเป็นจำนวนวินาทีนับจาก Epoch (Unix time) มี หลายวิธี initialize Time object:

  • Current time: Time.now
  • Unix timestamp + at method
  • ให้ starting date เป็นตัวเลขให้ Time.new (format: year/month/day)

แบบนี้:

Time.now # 2018-10-19 15:43:20 +0200
Time.new(2018, 1, 1) # 2018-01-01 00:00:00 +0100
Time.at(15000000000) # 2017-07-14 04:40:00 +0200

ขอ component ใดก็ได้จาก time object เช่น day, month, hour:

t = Time.now
puts t.day
puts t.month
puts t.hour

ยังขอได้ว่า date นี้ตรงวันไหนในสัปดาห์ เช่น "วันอาทิตย์ไหม?" predicate methods คืน true หรือ false

ตัวอย่าง:

t = Time.now
puts t.monday?
puts t.sunday?
puts t.friday?

ลองดู!

Time Zones

Time object มี time zone ใช้ zone method เช็ก time zone abbreviation ถ้าอยากได้ time zone offset 用 utc_offset output เป็นวินาที หาร 3600 ได้ชั่วโมง

ตัวอย่าง:

t = Time.now
t.zone # "CET"
t.utc_offset / 3600 # 1

ได้ current time ใน UTC:

Time.now.utc

Ruby Time Formatting

Ruby format Time objects แบบเฉพาะโดย default แต่อาจอยาก format อื่น ที่ ปรับตัวตาม use case ข่าวดี! มี เมธอด ได้เกือบ format 任何你想要的 คือ strftime (format time) ใช้ string พร้อม format specifiers แทนที่ด้วยค่า คล้าย printf

ตัวอย่าง:

time = Time.new
time.strftime("%d/%m/%Y") # "05/12/2015"
time.strftime("%k:%M") # "17:48"
time.strftime("%I:%M %p") # "11:04 PM"
time.strftime("Today is %A") # "Today is Sunday"
time.strftime("%d of %B, %Y") # "21 of December, 2015"
time.strftime("Unix time is %s") # "Unix time is 1449336630"

เมธอดนี้ยืดหยุ่นมาก ได้ time แยก date, หรือ date สวยพร้อมปี วัน ชื่อเดือน

Strftime Format Table

Format คำอธิบาย
%d วันของเดือน (01..31)
%m เดือนของปี (01..12) ใช้ %-m สำหรับ (1..12)
%k ชั่วโมง (0..23)
%M นาที
%S วินาที (00..60)
%I ชั่วโมง (1..12)
%p AM/PM
%Y ปี
%A วันของสัปดาห์ (ชื่อ)
%B เดือน (ชื่อ)

ข้อมูลเพิ่มเติม: https://strftime.net/ และ https://devdocs.io/ruby/time#method-i-strftime

Generating a Timestamp

สร้าง time-zone independent timestamp สำหรับ date specific events:

Time.now.to_i # 1549054305

Timestamp นี้เป็นวินาทีใน UTC (Coordinated Universal Time)

Time Difference (Addition และ Subtraction)

บางครั้งอยากเวลาในอนาคตหรืออดีต ไม่ใช่เวลาปัจจุบัน ทำ addition กับ time objects ได้! จำ internal representation เป็นวินาที:

# เพิ่ม 10 วินาที
time = Time.new + 10

ได้ time object ตั้ง 10 วินาทีจากตอนนี้ เช็กว่าเวลานั้นผ่านไปยัง:

Time.new > time

อยากได้วันวาน คำนวณวินาทีในหนึ่งวัน:

# seconds * minutes * hours
60 * 60 * 24 # 86400

ลบจาก current date:

Time.now - 86400

ถ้าใช้ Rails ทำแบบนี้ได้:

Time.now - 1.day

The Date Class

Date class ไม่มี concept ของ minutes, seconds, hours เก็บทุกอย่างเป็นวัน ต้อง require 'date' ใช้ Date.today ได้ current date ไม่เหมือน time Date.new ไม่ใช่ alias ของ today จดจำไว้

Date.today # Current date
Date.new # Returns a negative date

Date arithmetic คล้าย Time ต่างที่บวกลบวันแทนวินาที:

Date.today + 1 # เพิ่มหนึ่งวัน

Date ไม่รู้ hours, seconds, minutes ใช้ class นี้ตอนไม่ต้องการพวกนี้

Date & Time Parsing

Date.parse พยายาม parse string ที่ดูเหมือน date ใช้ heuristic algorithm detect input format บางครั้งให้ผลไม่ต้องการ

ตัวอย่าง:

Date.parse("10/10/2010") # -> 2010-10-10
Date.parse("September 3") # -> 2015-09-03
Date.parse("May I have a cup of coffee, please?") # -> 1 of May

ถ้าต้องการ strict ใช้ Date.iso8601 iso8601 date format: year-month-day ArgumentError exception ถ้า input invalid

ตัวอย่าง:

Date.iso8601("2018-10-01")

ใช้ Date.strptime กับ format specifiers กำหนด custom input format เอง specifiers เหมือน strftime

ตัวอย่าง:

Date.strptime("3 of September", "%d of %B") # 2015-09-03

Parse time 用 Time class ความหมาย: แปลง string '2018-01-01 00:00' เป็น Time object!

ตัวอย่าง:

require 'time'
Time.parse("September 20 18:00")

อยากให้ format input string เอง ใช้ strptime:

require 'time'
Time.strptime("1 of December 2017", "%d of %B %Y")

ความต่าง Time.parse และ Date.parse แค่ object ที่ได้กลับ (Time หรือ Date)

Date Constants

Date class มี constants ที่มีประโยชน์ เช่น array เดือนของปี และ array วันของสัปดาห์ เดือนเริ่ม index 1 mapping month number -> month name ตรงๆ วันเริ่ม Sunday แต่用 rotate ให้สัปดาห์เริ่ม Monday

Date::MONTHNAMES # (index 0 = nil)
Date::DAYNAMES.rotate(1)

The DateTime Class

DateTime subclass ของ Date เก็บ seconds เพิ่มเติมนอกจาก dates

ตัวอย่าง:

require 'date'
DateTime.superclass # Date
DateTime.now # DateTime: 2018-10-15T16:06:39+02:00

ทั้ง Time และ DateTime ทำงานเดียวกันได้ ความต่างหลัก: Time implemented in C เร็วกว่า

Performance:

Comparison: Time: 2644596.6 i/s DateTime: 231634.8 i/s - 11.42x slower

ActiveSupport – Time & Date Methods

ถ้าใช้ Rails คุ้นเคย 3.days.ago เมธอดเหล่านี้ไม่มีใน pure Ruby เพิ่มโดย ActiveSupport component ของ Rails ไม่คืน Time หรือ Date แต่ custom ActiveSupport class

1.hour.to_i # 3600
1.day # ActiveSupport::Duration
3.days.ago # ActiveSupport::TimeWithZone

Time math ได้ tomorrow's date:

Time.now + 1.day

Rails-exclusive time methods อื่นๆ:

date = Time.current
date.change(hour: 20)
date.at_beginning_of_day

Formatting:

date = Date.today
date.to_formatted_s(:short) # "16 Jul"
date.to_formatted_s(:long) # "July 16, 2018"

โค้ดเมธอดเหล่านี้ simple ควรดู source code TimeWithZone ด้วย

สรุป

ในบทความนี้เรียนรู้ Time และ Date classes, parse และ format time ใน Ruby และใช้ ActiveSupport time extensions

ขอบคุณที่อ่าน!