Ruby 日期 & 时间(Date & Time)

在 Ruby 中,日期(Date)时间(Time) 是处理日期和时间数据的核心类,分别由 DateTime 类提供。此外,DateTime 类结合了两者的功能。Ruby 的标准库和扩展库(如 ActiveSupport)提供了强大的日期和时间处理功能。以下是对 Ruby 日期和时间的中文讲解,涵盖创建、操作、常见方法等关键内容,力求简洁清晰。


1. Time 类

Time 类用于处理时间点,包含日期和时间信息,默认使用系统时区。

创建 Time 对象

  • 当前时间
  time = Time.now
  puts time  # 输出:2025-08-14 18:06:00 +0800(假设 HKT 时区)
  • 指定时间
  time = Time.new(2025, 8, 14, 18, 6, 0)
  puts time  # 输出:2025-08-14 18:06:00 +0000(默认 UTC)
  • 解析字符串(需 require 'time'):
  require 'time'
  time = Time.parse("2025-08-14 18:06:00")
  puts time  # 输出:2025-08-14 18:06:00 +0000

Time 常用方法

  • 获取时间组件
  time = Time.new(2025, 8, 14, 18, 6, 0)
  puts time.year   # 输出:2025
  puts time.month  # 输出:8
  puts time.day    # 输出:14
  puts time.hour   # 输出:18
  puts time.min    # 输出:6
  puts time.sec    # 输出:0
  • 格式化输出strftime):
  puts time.strftime("%Y-%m-%d %H:%M:%S")  # 输出:2025-08-14 18:06:00
  puts time.strftime("%A, %B %d")          # 输出:Thursday, August 14

常用格式化符号:

  • %Y:四位年份
  • %m:两位月份
  • %d:两位日期
  • %H:24 小时制小时
  • %M:分钟
  • %S:秒
  • %A:星期名
  • %B:月份名
  • 时间运算
  time = Time.now
  puts time + 3600  # 加 1 小时 输出:2025-08-14 19:06:00 +0800
  puts time - 3600  # 减 1 小时
  • 比较时间
  t1 = Time.new(2025, 8, 14)
  t2 = Time.new(2025, 8, 15)
  puts t1 < t2  # 输出:true

时区处理

Time 默认使用系统时区,可通过环境变量或库调整。

puts time.zone     # 输出:HKT(或系统时区)
puts time.utc      # 转换为 UTC 时间
puts time.localtime("+08:00")  # 转换为指定时区

2. Date 类

Date 类专注于日期处理,不包含时间信息(精确到天)。需 require 'date' 使用。

创建 Date 对象

  • 当前日期
  require 'date'
  date = Date.today
  puts date  # 输出:2025-08-14
  • 指定日期
  date = Date.new(2025, 8, 14)
  puts date  # 输出:2025-08-14
  • 解析字符串
  date = Date.parse("2025-08-14")
  puts date  # 输出:2025-08-14

Date 常用方法

  • 获取日期组件
  date = Date.new(2025, 8, 14)
  puts date.year   # 输出:2025
  puts date.month  # 输出:8
  puts date.day    # 输出:14
  puts date.wday   # 输出:4(星期四,0=星期日)
  • 日期运算
  puts date + 1     # 输出:2025-08-15(加 1 天)
  puts date - 1     # 输出:2025-08-13
  puts date >> 1    # 输出:2025-09-14(加 1 月)
  puts date << 1    # 输出:2025-07-14(减 1 月)
  • 格式化输出strftime):
  puts date.strftime("%Y/%m/%d")  # 输出:2025/08/14
  • 比较日期
  d1 = Date.new(2025, 8, 14)
  d2 = Date.new(2025, 8, 15)
  puts d1 < d2  # 输出:true

3. DateTime 类

DateTime 结合了 DateTime 的功能,包含日期和时间,适合需要高精度的时间点。

创建 DateTime 对象

require 'date'
datetime = DateTime.now
puts datetime  # 输出:2025-08-14T18:06:00+08:00
datetime = DateTime.new(2025, 8, 14, 18, 6, 0)
puts datetime  # 输出:2025-08-14T18:06:00+00:00

DateTime 常用方法

  • 类似 TimeDate,支持 year, month, hour, strftime 等。
  • 时区支持
  puts datetime.zone  # 输出:+00:00
  • 转换为 Time
  time = datetime.to_time
  puts time  # 输出:2025-08-14 18:06:00 +0000

4. 时间运算与间隔

  • Time 差值:返回秒数(Float)。
  t1 = Time.new(2025, 8, 14, 18, 0, 0)
  t2 = Time.new(2025, 8, 14, 18, 1, 0)
  puts t2 - t1  # 输出:60.0(秒)
  • Date 差值:返回天数(Rational)。
  require 'date'
  d1 = Date.new(2025, 8, 14)
  d2 = Date.new(2025, 8, 15)
  puts d2 - d1  # 输出:1

5. ActiveSupport 扩展(可选)

在 Rails 项目中,ActiveSupport 提供便捷的日期/时间方法(需 require 'active_support/time')。

  • 时间偏移
  require 'active_support/time'
  time = Time.now
  puts time + 1.hour   # 加 1 小时
  puts time - 2.days   # 减 2 天
  • 便捷方法
  puts time.beginning_of_day  # 当天 00:00:00
  puts time.end_of_month      # 当月最后一天

6. 注意事项

  • 时区处理Time 使用系统时区,DateTime 需显式指定时区,建议统一使用 UTC 或明确时区。
  • 性能TimeDateTime 更轻量,优先用于简单时间操作。
  • 依赖DateDateTimerequire 'date',而 Time 是核心类。
  • 格式化strftime 的格式化符号需熟悉,以满足不同输出需求。
  • 闰年与夏令时DateDateTime 自动处理闰年,Time 处理夏令时需注意时区。

7. 示例:综合应用

require 'date'

module TimeUtils
  def time_ago
    seconds = (Time.now - self).to_i
    case seconds
    when 0..59 then "#{seconds}秒前"
    when 60..3599 then "#{seconds / 60}分钟前"
    else "#{seconds / 3600}小时前"
    end
  end
end

class Time
  include TimeUtils
end

time = Time.new(2025, 8, 14, 17, 0, 0)
puts time.time_ago  # 输出:1小时前(假设当前时间为 18:06)

date = Date.today
puts date.strftime("%Y年%m月%d日")  # 输出:2025年08月14日

总结

Ruby 的 TimeDateDateTime 类提供了灵活的日期和时间处理功能。Time 适合处理具体时间点,Date 专注日期,DateTime 结合两者。常用方法如 strftime、时间运算和时区处理简化了开发。结合 ActiveSupport 可以进一步增强功能。注意时区和依赖问题,确保代码在多环境下的正确性。

如果你有具体问题或需要更详细的示例,请告诉我!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注