class Time

Time 对象表示一个日期和时间

Time.new(2000, 1, 1, 0, 0, 0) # => 2000-01-01 00:00:00 -0600

尽管它的值可以表示为单个数值(见下面的 时间戳秒数),但按部分处理该值可能更方便

t = Time.new(-2000, 1, 1, 0, 0, 0.0)
# => -2000-01-01 00:00:00 -0600
t.year # => -2000
t.month # => 1
t.mday # => 1
t.hour # => 0
t.min # => 0
t.sec # => 0
t.subsec # => 0

t = Time.new(2000, 12, 31, 23, 59, 59.5)
# => 2000-12-31 23:59:59.5 -0600
t.year # => 2000
t.month # => 12
t.mday # => 31
t.hour # => 23
t.min # => 59
t.sec # => 59
t.subsec # => (1/2)

时间戳秒数

时间戳秒数是自 Unix 纪元(1970 年 1 月 1 日)以来的确切秒数(包括小数子秒)。

您可以使用方法 Time.to_r 精确地检索该值

Time.at(0).to_r        # => (0/1)
Time.at(0.999999).to_r # => (9007190247541737/9007199254740992)

其他检索方法,例如 Time#to_iTime#to_f 可能会返回一个舍入或截断子秒的值。

时间分辨率

从系统时钟派生的 Time 对象(例如,通过方法 Time.now)具有系统支持的分辨率。

时间内部表示

Time 实现使用带符号的 63 位整数、IntegerRational。它是自纪元以来的纳秒数。带符号的 63 位整数可以表示 1823-11-12 到 2116-02-20。当使用 IntegerRational 时(在 1823 年之前、2116 年之后、纳秒以下),Time 的工作速度比使用带符号的 63 位整数时慢。

Ruby 使用 C 函数 localtimegmtime 在数字和 6 元组(年、月、日、小时、分钟、秒)之间进行映射。localtime 用于本地时间,而“gmtime”用于 UTC。

IntegerRational 没有范围限制,但由于 C 类型 time_tstruct tm,localtime 和 gmtime 有范围限制。如果超出该限制,Ruby 将外推 localtime 函数。

Time 类始终使用公历。也就是说,使用前摄公历。不支持其他日历,例如儒略历。

如果 time_t 是 32 位带符号整数,则它可以表示 1901-12-14 到 2038-01-19;如果它是 64 位带符号整数,则可以表示 -292277022657-01-27 到 292277026596-12-05。但是,某些平台上的 localtime 不支持负 time_t(1970 年之前)。

struct tm 有一个 tm_year 成员来表示年份。(tm_year = 0 表示 1900 年。)它在 C 标准中定义为 int。如果 int 是 32 位,则 tm_year 可以表示 -2147481748 到 2147485547 之间的值。

如果 C 函数 localtimegmtime 支持,Ruby 就支持闰秒。它们在大多数 Unix 系统中使用 tz 数据库。tz 数据库有支持闰秒的时区。例如,“Asia/Tokyo”不支持闰秒,但“right/Asia/Tokyo”支持闰秒。因此,如果大多数 Unix 系统中的 TZ 环境变量设置为“right/Asia/Tokyo”,Ruby 将支持闰秒。

示例

所有这些示例都使用 EST 时区(GMT-5)完成。

创建新的 Time 实例

您可以使用 Time.new 创建 Time 的新实例。这将使用当前的系统时间。Time.now 是它的别名。您还可以将时间部分(例如年、月、分等)传递给 Time.new。当您想以这种方式构造时间时,您必须至少传递年份。如果您仅传递年份,则时间将默认为该年的 1 月 1 日 00:00:00,并且使用当前的系统时区。以下是一些示例

Time.new(2002)         #=> 2002-01-01 00:00:00 -0500
Time.new(2002, 10)     #=> 2002-10-01 00:00:00 -0500
Time.new(2002, 10, 31) #=> 2002-10-31 00:00:00 -0500

您可以传递 UTC 偏移量

Time.new(2002, 10, 31, 2, 2, 2, "+02:00") #=> 2002-10-31 02:02:02 +0200

或者 时区对象

zone = timezone("Europe/Athens")      # Eastern European Time, UTC+2
Time.new(2002, 10, 31, 2, 2, 2, zone) #=> 2002-10-31 02:02:02 +0200

您还可以使用 Time.localTime.utc 来推断本地时区和 UTC 时区,而不是使用当前的系统设置。

您还可以使用 Time.at 创建新时间,该方法使用自 Unix 纪元以来的秒数(带子秒)。

Time.at(628232400) #=> 1989-11-28 00:00:00 -0500

使用 Time 的实例

一旦您拥有 Time 的实例,您就可以使用它做很多事情。以下是一些示例。对于以下所有示例,我们将假设您已执行以下操作

t = Time.new(1993, 02, 24, 12, 0, 0, "+09:00")

那是星期一吗?

t.monday? #=> false

那是哪一年来着?

t.year #=> 1993

当时是夏令时吗?

t.dst? #=> false

一年后的那天是哪天?

t + (60*60*24*365) #=> 1994-02-24 12:00:00 +0900

自 Unix 纪元以来过了多少秒?

t.to_i #=> 730522800

您还可以执行标准函数,例如比较两个时间。

t1 = Time.new(2010)
t2 = Time.new(2011)

t1 == t2 #=> false
t1 == t1 #=> true
t1 <  t2 #=> true
t1 >  t2 #=> false

Time.new(2010,10,31).between?(t1, t2) #=> true

这里有什么

首先,看看其他地方有什么。类 Time

在这里,类 Time 提供了对以下操作有用的方法

用于创建的方法

用于获取的方法

用于查询的方法

用于比较的方法

用于转换的方法

用于舍入的方法

有关参数 zone 的形式,请参阅 时区指定符

时区指定符

某些 Time 方法接受指定时区的参数

这些方法中的任何一个给定的值都必须是以下值之一(以下详细说明)

时/分偏移量

zone 值可以是 UTC 的字符串偏移量,格式为 '+HH:MM''-HH:MM',其中

示例

t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC
Time.at(t, in: '-23:59')            # => 1999-12-31 20:16:01 -2359
Time.at(t, in: '+23:59')            # => 2000-01-02 20:14:01 +2359

单字母偏移量

zone 值可以是 'A'..'I''K'..'Z' 范围内的字母;请参阅 军事时区列表

t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC
Time.at(t, in: 'A')                 # => 2000-01-01 21:15:01 +0100
Time.at(t, in: 'I')                 # => 2000-01-02 05:15:01 +0900
Time.at(t, in: 'K')                 # => 2000-01-02 06:15:01 +1000
Time.at(t, in: 'Y')                 # => 2000-01-01 08:15:01 -1200
Time.at(t, in: 'Z')                 # => 2000-01-01 20:15:01 UTC

整数偏移量

zone 值可以是 -86399..86399 范围内的整数秒数

t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC
Time.at(t, in: -86399)              # => 1999-12-31 20:15:02 -235959
Time.at(t, in: 86399)               # => 2000-01-02 20:15:00 +235959

时区对象

zone 值可以是一个响应某些时区方法的对象,例如 TimezoneTZInfo 的实例。

时区方法是

自定义时区类可以具有这些实例方法,如果定义了这些方法,则将调用这些方法

Time-类对象

Time-类对象是一个容器对象,能够与时区库进行时区转换。

上述时区转换方法的参数将具有与 Time 类似的属性,但与时区相关的属性除外,它们是无意义的。

时区对象的 local_to_utcutc_to_local 方法返回的对象可以与其参数的类相同,也可以是任意对象类或 Integer 类。

对于返回的 Integer 以外的类,该类必须具有以下方法

对于返回的 Integer,其在 UTC 中分解的组件被解释为指定时区的时间。

时区名称

如果类(类方法的接收者,或实例方法的接收者的类)具有 find_timezone 单例方法,则调用此方法以从时区名称中获取相应的时区对象。

例如,使用 Timezone

class TimeWithTimezone < Time
  require 'timezone'
  def self.find_timezone(z) = Timezone[z]
end

TimeWithTimezone.now(in: "America/New_York")        #=> 2023-12-25 00:00:00 -0500
TimeWithTimezone.new("2023-12-25 America/New_York") #=> 2023-12-25 00:00:00 -0500

或者,使用 TZInfo

class TimeWithTZInfo < Time
  require 'tzinfo'
  def self.find_timezone(z) = TZInfo::Timezone.get(z)
end

TimeWithTZInfo.now(in: "America/New_York")          #=> 2023-12-25 00:00:00 -0500
TimeWithTZInfo.new("2023-12-25 America/New_York")   #=> 2023-12-25 00:00:00 -0500

您可以为每个子类或顶级 Time 类定义此方法。