Ruby 日期与时间
Ruby 中的日期与时间
Section titled “Ruby 中的日期与时间”Ruby 通过其核心的 Time 类和标准库中的 Date 和 DateTime 类(位于 date 库中,可能需要 require)提供了强大的日期和时间处理支持。Time 类表示一个特定的时刻,包括日期和时间两个组件,在大多数现代系统上精确到微秒。
在现代 64 位系统上,Ruby 的 Time 对象可以表示非常大的日期范围,远远超过了影响了一些旧的 32 位系统的 1970-2038 限制。
获取当前日期和时间
Section titled “获取当前日期和时间”您可以使用 Time.now 或其别名 Time.new(在不带参数调用时)获取当前系统日期和时间。
#!/usr/bin/env ruby
time_now = Time.nowputs "当前时间 (Time.now): #{time_now.inspect}"
# Time.new 在不带参数调用时是 Time.now 的别名time_new = Time.newputs "当前时间 (Time.new): #{time_new.inspect}"这将产生类似以下的输出(具体的时间和时区会有所不同):
Current Time (Time.now): 2023-10-27 10:30:45.123456 -0700Current Time (Time.new): 2023-10-27 10:30:45.123456 -0700Time 对象的组成部分
Section titled “Time 对象的组成部分”一个 Time 对象提供方法来访问其各种组成部分:
#!/usr/bin/env ruby
time = Time.now
puts "当前时间: #{time.inspect}"puts "年份: #{time.year}" # 例如 2023puts "月份: #{time.month}" # 1 (一月) 到 12 (十二月)puts "日期: #{time.day}" # 1 到 31puts "小时: #{time.hour}" # 0 到 23 (24 小时制)puts "分钟: #{time.min}" # 0 到 59puts "秒钟: #{time.sec}" # 0 到 59 (闰秒时可为 60)puts "微秒: #{time.usec}" # 0 到 999999puts "纳秒: #{time.nsec}" # 0 到 999999999 (比微秒更精确)puts "一周中的第几天 (wday): #{time.wday}" # 0 (星期日) 到 6 (星期六)puts "一年中的第几天 (yday): #{time.yday}" # 1 到 365 (闰年为 366)puts "时区: #{time.zone}" # 例如 "PST", "UTC", "EDT" (可能为 nil)puts "是夏令时吗?: #{time.dst?}" # 如果夏令时生效则为 true为特定日期/时间创建 Time 对象
Section titled “为特定日期/时间创建 Time 对象”您可以使用以下方法为特定日期和时间创建 Time 对象:
Time.local(year, month, day, hour, min, sec, usec_with_frac)或Time.mktime(…): 在系统的本地时区创建一个Time对象。Time.utc(year, month, day, hour, min, sec, usec_with_frac)或Time.gm(…): 在协调世界时 (UTC),也称为格林威治标准时间 (GMT) 中创建一个Time对象。
#!/usr/bin/env ruby
# 2025 年 12 月 25 日 14:30:00 本地时间local_time = Time.local(2025, 12, 25, 14, 30, 0)puts "本地时间: #{local_time.inspect}"
# 2024 年 7 月 4 日 09:15:00 UTCutc_time = Time.utc(2024, 7, 4, 9, 15, 0)puts "UTC 时间: #{utc_time.inspect}"
# 从右到左可以省略部分;它们默认为最小值 (例如月/日为 1,时间组件为 0)start_of_year = Time.local(2023) # 2023 年 1 月 1 日 00:00:00 本地时间puts "2023 年初: #{start_of_year.inspect}"Time 对象的转换
Section titled “Time 对象的转换”Time 对象可以转换为各种其他表示形式:
time.to_a: 返回一个 10 元素的数组:[秒, 分, 时, 日, 月, 年, 一周中的第几天, 一年中的第几天, 是否夏令时, 时区缩写]。time.to_i或time.tv_sec: 返回自 Unix 纪元 (1970 年 1 月 1 日 00:00:00 UTC) 以来的秒数。time.to_f或time.tv_usec与tv_sec结合使用: 返回自纪元以来的秒数 (浮点数),包括微秒。Time.at(seconds_since_epoch): 从自纪元以来的秒数创建一个Time对象。
#!/usr/bin/env ruby
time = Time.now
components_array = time.to_aputs "时间作为数组: #{components_array.inspect}"# 示例:[15, 30, 10, 27, 10, 2023, 5, 300, true, "PDT"]
seconds_epoch = time.to_iputs "自纪元以来的秒数: #{seconds_epoch}"
reconstructed_time = Time.at(seconds_epoch)puts "从秒数重构的时间: #{reconstructed_time.inspect}"时区和夏令时 (DST)
Section titled “时区和夏令时 (DST)”Ruby 的 Time 对象是时区感知的。您可以在时区之间进行转换:
#!/usr/bin/env ruby
time = Time.now # 在本地时区创建
puts "原始 (本地): #{time.inspect} (时区: #{time.zone}, 夏令时: #{time.dst?})"
# 转换为 UTCutc_time = time.utcputs "UTC: #{utc_time.inspect} (时区: #{utc_time.zone}, 夏令时: #{utc_time.dst?})"
# 将 UTC 时间转换回本地时区local_again = utc_time.localtimeputs "再次转换为本地时间: #{local_again.inspect} (时区: #{local_again.zone}, 夏令时: #{local_again.dst?})"
# 获取一个新的 UTC 或本地时区 Time 对象,而不修改原始对象new_utc_obj = time.getutcnew_local_obj = utc_time.getlocal
puts "原始时间是 UTC 吗? #{time.utc?}" # false (如果本地时间不是 UTC)puts "utc_time 对象是 UTC 吗? #{utc_time.utc?}" # true
puts "UTC 偏移量: #{time.utc_offset} 秒" # 例如 PDT 的 -25200 (-7 小时)使用 strftime 格式化时间和日期
Section titled “使用 strftime 格式化时间和日期”strftime (字符串格式化时间) 方法是一个强大的工具,用于将 Time 对象自定义格式化为字符串。它使用指令(以百分号开头的字符)来指定时间的每个部分应如何表示。
#!/usr/bin/env ruby
time = Time.now
puts "默认 to_s: #{time.to_s}" # 例如 2023-10-27 10:30:45 -0700puts "ctime: #{time.ctime}" # 例如 Fri Oct 27 10:30:45 2023puts "ISO 8601: #{time.iso8601}" # 例如 2023-10-27T10:30:45-07:00
puts "自定义格式 (YYYY-MM-DD HH:MM:SS): #{time.strftime("%Y-%m-%d %H:%M:%S")}"puts "自定义格式 (月 日, 年): #{time.strftime("%B %d, %Y")}"puts "自定义格式 (hh:mm AM/PM 时区): #{time.strftime("%I:%M %p %Z")}"常用 strftime 指令:
Section titled “常用 strftime 指令:”| 指令 | 描述 |
|---|---|
%Y | 带世纪的年份 (例如 2023) |
%y | 不带世纪的年份 (00-99) |
%m | 年份中的月份 (01-12) |
%B | 月份的全名 (例如 January) |
%b 或 %h | 月份的缩写名 (例如 Jan) |
%d | 月份中的日期 (01-31) |
%e | 月份中的日期 (前面有空格填充) ( 1-31) |
%A | 一周中的全名 (例如 Sunday) |
%a | 一周中的缩写名 (例如 Sun) |
%w | 一周中的第几天 (星期日为 0, 0-6) |
%H | 一天中的小时 (24 小时制) (00-23) |
%I | 一天中的小时 (12 小时制) (01-12) |
%M | 小时中的分钟 (00-59) |
%S | 分钟中的秒数 (00-60) (闰秒为 60) |
%L | 秒中的毫秒数 (000-999) |
%N | 秒中的纳秒数 (000000000-999999999) |
%p | 上午/下午指示符 (AM 或 PM) |
%Z | 时区缩写名称 |
%z | 与 UTC 的时区偏移量 (例如 +0900, -0700) |
%:z | 带冒号的时区偏移量 (例如 +09:00) |
%c | 特定于区域设置的日期和时间 (例如 Fri Oct 27 10:30:45 2023) |
%x | 特定于区域设置的日期表示 (例如 10/27/23) |
%X | 特定于区域设置的时间表示 (例如 10:30:45) |
%% | 字面上的 ’%’ 字符 |
您可以对 Time 对象执行算术运算。添加或减去一个数值时,该数字被视为秒数。
#!/usr/bin/env ruby
now = Time.nowputs "当前时间: #{now}"
one_hour_ago = now - 3600 # 3600 秒 = 1 小时puts "一小时前: #{one_hour_ago}"
two_days_from_now = now + (2 * 24 * 60 * 60) # 添加 2 天对应的秒数puts "两天后: #{two_days_from_now}"
difference = two_days_from_now - now # 两个 Time 对象之间的差以秒为单位 (浮点数)puts "差异 (秒): #{difference}"puts "差异 (天): #{difference / (24 * 60 * 60)}"输出 (示例):
Current time: 2023-10-27 10:45:00 -0700One hour ago: 2023-10-27 09:45:00 -0700Two days from now: 2023-10-29 10:45:00 -0700Difference in seconds: 172800.0Difference in days: 2.0使用 Date 和 DateTime 进行特定日期操作
Section titled “使用 Date 和 DateTime 进行特定日期操作”对于主要关注日期的操作(不带时间组件)或需要历史日期计算(例如儒略历/格里高利历改革)的场景,标准库 date 中的 Date 和 DateTime 类通常更适合。您需要 require ‘date’ 才能使用它们。
#!/usr/bin/env rubyrequire 'date'
today = Date.todayputs "今天 (Date): #{today.inspect}" # 例如 #<Date: 2023-10-27 ((2460245j,0s,0n),+0s,2299161j)>puts "格式化的日期: #{today.strftime('%A, %B %d, %Y')}"
yesterday = today - 1puts "昨天: #{yesterday}"
next_month = today >> 1 # 增加一个月puts "下个月: #{next_month}"
# DateTime 包括时间组件dt_now = DateTime.nowputs "当前 DateTime: #{dt_now.inspect}"