Time là lớp Ruby giúp biểu diễn thời điểm cụ thể.
Đọc xong bài này bạn sẽ học mọi thứ cần để thành pháp sư thời gian Ruby!
Chủ đề bao gồm:
- Chuyển chuỗi thành đối tượng time
- Phân rã time thành thành phần (ngày/giờ/giây…)
- Dùng lớp
Date,DateTime&Timetrong Ruby - Định dạng time bất kỳ cách bạn muốn
- Tìm khoảng cách giữa hai đối tượng
Time
Làm ngay!
Lớp Time Ruby
Dùng lớp Time biểu diễn thời gian & ngày.
Ngày có ba thành phần:
- ngày
- tháng
- năm
Và giờ:
- giờ
- phút
- giây
Thông tin lưu bởi lớp Time là số giây từ Epoch, còn gọi là Unix time.
Có vài cách khởi tạo đối tượng Time:
- Lấy đối tượng thời gian hiện tại bằng
Time.now - Tạo
Timetừ Unix timestamp & phương thứcat - Cho ngày bắt đầu dạng số cho
Time.new(định dạng: năm/tháng/ngày)
Như sau:
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
Bạn hỏi đối tượng time bất kỳ thành phần.
Ví dụ…
Hỏi ngày, tháng, giờ đối tượng time biểu diễn:
t = Time.now
puts t.day
puts t.month
puts t.hour
Thêm vào đó, cũng hỏi ngày đó có phải ngày tuần cụ thể không.
Ví dụ:
"Ngày này có phải Chủ Nhật không?".
Đây là predicate methods, trả về true hoặc false.
Ví dụ:
t = Time.now
puts t.monday?
puts t.sunday?
puts t.friday?
Thử đi!
Múi Giờ
Đối tượng Time có múi giờ liên kết.
Kiểm tra múi giờ hiện tại cho Time dùng phương thức zone.
Cho viết tắt múi giờ.
Muốn độ lệch múi giờ dùng utc_offset. Đầu ra phương thức này tính bằng giây, chia 3600 ra giờ.
Ví dụ:
t = Time.now
t.zone # "CET"
t.utc_offset / 3600 # 1
Cũng lấy thời gian hiện tại UTC:
Time.now.utc
Định Dạng Time Ruby
Ruby định dạng Time theo cách mặc định.
Nhưng bạn có thể muốn khác.
Điều thích ứng trường hợp dùng.
Tin tốt!
Có thể dùng một phương thức lấy gần như bất kỳ định dạng nào cần.
Phương thức là strftime, cơ bản nghĩa 'format time'.
Hoạt động bằng cách truyền chuỗi với format specifier, specifier sẽ được thay bằng giá trị. Nếu từng dùng printf ý tưởng rất giống.
Xem ví dụ:
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"
Như thấy, phương thức rất linh hoạt. Lấy giờ không ngày, hoặc ngày đẹp với năm, ngày & tên tháng hiện tại.
Bảng Định Dạng Strftime
| Định dạng | Mô tả |
|---|---|
| %d | Ngày tháng (01..31) |
| %m | Tháng năm (01..12) Dùng %-m cho (1..12) |
| %k | Giờ (0..23) |
| %M | Phút |
| %S | Giây (00..60) |
| %I | Giờ (1..12) |
| %p | AM/PM |
| %Y | Năm |
| %A | Ngày tuần (tên) |
| %B | Tháng (tên) |
Thêm info định dạng tại:
- https://strftime.net/
- https://devdocs.io/ruby/time#method-i-strftime
Tạo Timestamp
Tạo timestamp độc lập múi giờ đánh dấu sự kiện cụ thể.
Cách làm:
Time.now.to_i # 1549054305
Timestamp này là số giây UTC (Coordinated Universal Time).
Khoảng Cách Thời Gian (Cộng & Trừ)
Đôi khi không muốn thời gian hiện tại, mà thời gian tương lai/quá khứ.
Có thể cộng với đối tượng time!
Nhớ biểu diễn nội bộ Time tính bằng giây, nên làm:
# Cộng mười giây
time = Time.new + 10
Ví dụ này cho đối tượng time thiết lập 10 giây từ hiện tại.
Rồi kiểm tra thời gian đó đã qua chưa.
Time.new > time
Muốn lấy ngày hôm qua thì tính số giây trong ngày.
Như sau:
# giây * phút * giờ
60 * 60 * 24 # 86400
Với số này trừ từ ngày hiện tại:
Time.now - 86400
Nếu dùng Rails thì làm:
Time.now - 1.day
Lớp Date
Lớp Date không có khái niệm phút, giây, giờ. Lớp này lưu mọi thứ về mặt ngày.
Để dùng Date cần require 'date'.
Lấy ngày hiện tại bằng Date.today.
Khác time, Date.new không phải alias cho today, nhớ điều đó.
Date.today # Ngày hiện tại
Date.new # Trả về ngày âm
Toán học Date tương tự Time, khác là cộng ngày thay vì giây.
Date.today + 1 # Cộng một ngày
Date không biết giờ, giây, phút, chỉ dùng lớp này nếu không cần chúng.
Phân Tích Date & Time
Phương thức Date.parse cố gắng parse bất kỳ chuỗi trông như ngày.
Dùng thuật toán heuristic đơn giản cố phát hiện định dạng đầu vào.
Đôi khi cho kết quả không mong muốn.
Ví dụ:
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
Cần cái nghiêm ngặt hơn dùng Date.iso8601.
Ngày iso8601 định dạng:
year-month-day
Exception ArgumentError ném ra nếu đầu vào không hợp lệ.
Ví dụ:
Date.iso8601("2018-10-01")
Dùng Date.strptime & bộ format specifier cung cấp định dạng đầu vào tùy chỉnh. Specifier giống dùng cho strftime.
Ví dụ:
Date.strptime("3 of September", "%d of %B") # 2015-09-03
Parse time dùng lớp Time.
Nói cách khác:
Chuyển chuỗi như '2018-01-01 00:00' thành đối tượng Time!
Ví dụ:
require 'time'
Time.parse("September 20 18:00")
Muốn cung cấp định dạng chuỗi đầu vào dùng strptime.
Như sau:
require 'time'
Time.strptime("1 of December 2017", "%d of %B %Y")
Khác biệt giữa Time.parse & Date.parse chỉ là loại đối tượng trả về (Time hoặc Date).
Hằng Số Date
Lớp Date có hằng số hữu ích.
Ví dụ, mảng tháng năm và mảng ngày tuần.
Tháng bắt đầu index 1 để ánh xạ trực tiếp số tháng -> tên tháng.
Ngày bắt đầu Chủ Nhật, nhưng dùng rotate để tuần bắt đầu Thứ Hai.
Date::MONTHNAMES # (index 0 = nil)
Date::DAYNAMES.rotate(1)
Lớp DateTime
Lớp DateTime là con của Date và lưu giây ngoài ngày.
Ví dụ:
require 'date'
DateTime.superclass # Date
DateTime.now # DateTime: 2018-10-15T16:06:39+02:00
Cả Time và DateTime làm cùng việc, khác chính là Time triển khai bằng C, nên nhanh hơn.
Hiệu năng:
Comparison: Time: 2644596.6 i/s
DateTime: 231634.8 i/s - 11.42x slower
ActiveSupport – Phương Thức Time & Date
Nếu dùng Rails chắc quen 3.days.ago.
Phương thức này không có trong Ruby thuần, thêm bởi thành phần ActiveSupport của Rails.
Ví dụ, chú ý phương thức không trả Time hoặc Date, mà lớp ActiveSupport tùy chỉnh.
1.hour.to_i # 3600
1.day # ActiveSupport::Duration
3.days.ago # ActiveSupport::TimeWithZone
Làm toán thời gian với chúng & lấy ngày mai:
Time.now + 1.day
Phương thức time độc quyền Rails khác:
date = Time.current
date.change(hour: 20)
date.at_beginning_of_day
Và định dạng:
date = Date.today
date.to_formatted_s(:short) # "16 Jul"
date.to_formatted_s(:long) # "July 16, 2018"
Code các phương thức này thực sự đơn giản, nên xem. Source TimeWithZone cũng đáng xem.
Tóm Tắt
Bài này bạn học lớp Time & Date, parse & format time Ruby, dùng extension ActiveSupport time.
Cảm ơn đã đọc!