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_i
和 Time#to_f
)可能会返回一个舍入或截断子秒的值。
时间分辨率¶ ↑
从系统时钟导出的 Time
对象(例如,通过方法 Time.now
)具有系统支持的分辨率。
时间内部表示¶ ↑
Time
实现使用带符号的 63 位整数,Integer
或 Rational
。 它是自 纪元 以来经过的纳秒数。 带符号的 63 位整数可以表示 1823-11-12 到 2116-02-20。 当使用 Integer
或 Rational
(在 1823 年之前,2116 年之后,小于纳秒)时,Time
的工作速度比使用带符号的 63 位整数时慢。
Ruby 使用 C 函数 localtime
和 gmtime
在数字和 6 元组(年、月、日、时、分、秒)之间进行映射。 localtime
用于本地时间,“gmtime”用于 UTC。
Integer
和 Rational
没有范围限制,但由于 C 类型 time_t
和 struct 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 函数 localtime
和 gmtime
支持闰秒,则 Ruby 也支持闰秒。 它们在大多数 Unix 系统中使用 tz 数据库。 tz 数据库具有支持闰秒的时区。 例如,“Asia/Tokyo”不支持闰秒,但“right/Asia/Tokyo”支持闰秒。 因此,如果 TZ 环境变量在大多数 Unix 系统中设置为“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.local
和 Time.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
-
继承自 类 Object。
-
包含 模块 Comparable。
在这里,类 Time
提供了对以下内容有用的方法:
创建方法¶ ↑
-
::new
:从指定的参数(年、月等)返回一个新的时间,包括可选的时区值。 -
::at
:返回基于自纪元以来秒数的新时间。 -
::now
:返回基于当前系统时间的新时间。 -
+
(加号):返回一个新的时间,增加给定的秒数。 -
-
(减号):返回一个新的时间,减少给定的秒数。
获取方法¶ ↑
-
year
:返回时间年份。 -
hour
:返回时间的小时值。 -
min
:返回时间的分钟值。 -
sec
:返回时间的秒数值。 -
subsec
:返回时间的子秒值。 -
wday
:返回时间的整数星期几值(0 == 星期日)。 -
yday
:返回时间的整数年份日期值(1 == 1 月 1 日)。 -
hash
:返回时间的整数哈希值。 -
utc_offset
(别名为gmt_offset
和gmtoff
):返回时间与 UTC 之间的偏移秒数。 -
to_f
:返回时间的自纪元以来的浮点秒数。 -
zone
:返回时间时区的字符串表示形式。
查询方法¶ ↑
-
sunday?
:返回时间是否为星期日。 -
monday?
:返回时间是否为星期一。 -
tuesday?
:返回时间是否为星期二。 -
wednesday?
:返回时间是否为星期三。 -
thursday?
:返回时间是否为星期四。 -
friday?
:返回时间是否为星期五。 -
saturday?
:返回时间是否为星期六。
比较方法¶ ↑
-
#<=>: 将
self
与另一个时间进行比较。 -
eql?
: 返回时间是否与另一个时间相等。
转换方法¶ ↑
-
inspect
: 将详细的时间信息作为字符串返回。 -
strftime
: 根据给定的格式,将时间作为字符串返回。 -
to_a
: 返回一个包含时间值的10元素数组。 -
to_s
: 返回时间的字符串表示。 -
getlocal
: 返回转换为本地时间的新时间。 -
localtime
: 将时间就地转换为本地时间。 -
deconstruct_keys
: 返回用于模式匹配的时间组件的哈希值。
舍入方法¶ ↑
有关参数 zone
的形式,请参见时区指定符。
时区指定符¶ ↑
某些 Time
方法接受指定时区的参数。
-
Time.at
: 关键字参数in:
。 -
Time.new
: 位置参数zone
或关键字参数in:
。 -
Time.now
: 关键字参数in:
。 -
Time#getlocal
: 位置参数zone
。 -
Time#localtime
: 位置参数zone
。
使用这些中的任何一个给定的值必须是以下之一(每个在下面详细说明)
小时/分钟偏移量¶ ↑
zone 值可以是 '+HH:MM'
或 '-HH:MM'
形式的 UTC 字符串偏移量,其中
-
HH
是 2 位数的小时,范围为0..23
。 -
MM
是 2 位数的分钟,范围为0..59
。
示例
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 值可以是响应特定时区方法(例如 Timezone 和 TZInfo)的对象实例。
时区方法有
-
local_to_utc
:当使用位置参数
zone
或关键字参数in:
的值tz
调用Time.new
时调用。 -
utc_to_local
:当使用关键字参数
in:
的值tz
调用Time.at
或Time.now
,以及当使用位置参数zone
的值tz
调用Time#getlocal
或Time#localtime
时调用。UTC 偏移量将计算为原始时间和返回的对象之间的差值,作为
Integer
。 如果对象是固定偏移量,则也会计算其utc_offset
。
自定义时区类可能具有以下实例方法,如果定义了这些方法,则会调用这些方法
-
abbr
:当使用涉及
%Z
的格式调用Time#strftime
时调用。- 参数
- 返回
-
时区名称的字符串缩写。
-
dst?
:当使用关键字参数
in:
的值tz
调用Time.at
或Time.now
,以及当使用位置参数zone
的值tz
调用Time#getlocal
或Time#localtime
时调用。- 参数
- 返回
-
时间是否为夏令时。
-
name
:当调用
Marshal.dump(t)
时调用- 参数
-
无。
- 返回
-
时区的字符串名称。
Time
类对象¶ ↑
Time
类对象是一个能够与时区库接口进行时区转换的容器对象。
上面时区转换方法的参数将具有类似于 Time
的属性,除了与时区相关的属性没有意义。
时区对象的 local_to_utc
和 utc_to_local
方法返回的对象可以是与其参数相同的类,可以是任意对象类,也可以是类 Integer
。
对于返回的除 Integer
以外的类,该类必须具有以下方法
-
year
-
mon
-
mday
-
hour
-
min
-
sec
-
isdst
-
to_i
对于返回的 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
类上定义此方法。
公共类方法
根据给定的参数返回一个新的 Time
对象。
必需的参数 time
可以是以下之一
-
一个
Time
对象,其值是返回时间的基础; 也受可选关键字参数in:
的影响(见下文)。 -
返回时间的 Epoch 秒数数值。
示例
t = Time.new(2000, 12, 31, 23, 59, 59) # => 2000-12-31 23:59:59 -0600 secs = t.to_i # => 978328799 Time.at(secs) # => 2000-12-31 23:59:59 -0600 Time.at(secs + 0.5) # => 2000-12-31 23:59:59.5 -0600 Time.at(1000000000) # => 2001-09-08 20:46:40 -0500 Time.at(0) # => 1969-12-31 18:00:00 -0600 Time.at(-1000000000) # => 1938-04-24 17:13:20 -0500
可选的数字参数 subsec
和可选的符号参数 units
一起用于指定返回时间的子秒; 参数 units
指定 subsec
的单位
-
:millisecond
:subsec
单位为毫秒Time.at(secs, 0, :millisecond) # => 2000-12-31 23:59:59 -0600 Time.at(secs, 500, :millisecond) # => 2000-12-31 23:59:59.5 -0600 Time.at(secs, 1000, :millisecond) # => 2001-01-01 00:00:00 -0600 Time.at(secs, -1000, :millisecond) # => 2000-12-31 23:59:58 -0600
-
:microsecond
或:usec
:subsec
单位为微秒Time.at(secs, 0, :microsecond) # => 2000-12-31 23:59:59 -0600 Time.at(secs, 500000, :microsecond) # => 2000-12-31 23:59:59.5 -0600 Time.at(secs, 1000000, :microsecond) # => 2001-01-01 00:00:00 -0600 Time.at(secs, -1000000, :microsecond) # => 2000-12-31 23:59:58 -0600
-
:nanosecond
或:nsec
:subsec
单位为纳秒Time.at(secs, 0, :nanosecond) # => 2000-12-31 23:59:59 -0600 Time.at(secs, 500000000, :nanosecond) # => 2000-12-31 23:59:59.5 -0600 Time.at(secs, 1000000000, :nanosecond) # => 2001-01-01 00:00:00 -0600 Time.at(secs, -1000000000, :nanosecond) # => 2000-12-31 23:59:58 -0600
可选的关键字参数 in: zone
指定返回时间的时区
Time.at(secs, in: '+12:00') # => 2001-01-01 17:59:59 +1200 Time.at(secs, in: '-12:00') # => 2000-12-31 17:59:59 -1200
有关参数 zone
的形式,请参见时区指定符。
# File ruby_3_4_1/timev.rb, line 323 def self.at(time, subsec = false, unit = :microsecond, in: nil) if Primitive.mandatory_only? Primitive.time_s_at1(time) else Primitive.time_s_at(time, subsec, unit, Primitive.arg!(:in)) end end
根据给定的参数,以 UTC 时区返回一个新的 Time
对象。
当给出 1 到 7 个参数时,这些参数的解释与上面的第一个调用序列相同
Time.utc(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0)
示例
Time.utc(2000) # => 2000-01-01 00:00:00 UTC Time.utc(-2000) # => -2000-01-01 00:00:00 UTC
所需的参数 year
没有最小值和最大值。
对于可选参数
-
month
:月份,范围 (1..12),或不区分大小写的 3 个字母的月份名称Time.utc(2000, 1) # => 2000-01-01 00:00:00 UTC Time.utc(2000, 12) # => 2000-12-01 00:00:00 UTC Time.utc(2000, 'jan') # => 2000-01-01 00:00:00 UTC Time.utc(2000, 'JAN') # => 2000-01-01 00:00:00 UTC
-
mday
:月份中的天数,范围 (1..31)Time.utc(2000, 1, 1) # => 2000-01-01 00:00:00 UTC Time.utc(2000, 1, 31) # => 2000-01-31 00:00:00 UTC
-
hour
:小时,范围 (0..23),如果min
、sec
和usec
为零,则为 24Time.utc(2000, 1, 1, 0) # => 2000-01-01 00:00:00 UTC Time.utc(2000, 1, 1, 23) # => 2000-01-01 23:00:00 UTC Time.utc(2000, 1, 1, 24) # => 2000-01-02 00:00:00 UTC
-
min
:分钟,范围 (0..59)Time.utc(2000, 1, 1, 0, 0) # => 2000-01-01 00:00:00 UTC Time.utc(2000, 1, 1, 0, 59) # => 2000-01-01 00:59:00 UTC
-
sec
:秒,范围 (0..59),如果usec
为零,则为 60Time.utc(2000, 1, 1, 0, 0, 0) # => 2000-01-01 00:00:00 UTC Time.utc(2000, 1, 1, 0, 0, 59) # => 2000-01-01 00:00:59 UTC Time.utc(2000, 1, 1, 0, 0, 60) # => 2000-01-01 00:01:00 UTC
-
usec
:微秒,范围 (0..999999)Time.utc(2000, 1, 1, 0, 0, 0, 0) # => 2000-01-01 00:00:00 UTC Time.utc(2000, 1, 1, 0, 0, 0, 999999) # => 2000-01-01 00:00:00.999999 UTC
这些值可以是
-
整数,如上所述。
-
可转换为整数的数值
Time.utc(Float(0.0), Rational(1, 1), 1.0, 0.0, 0.0, 0.0, 0.0) # => 0000-01-01 00:00:00 UTC
-
String
整数a = %w[0 1 1 0 0 0 0 0] # => ["0", "1", "1", "0", "0", "0", "0", "0"] Time.utc(*a) # => 0000-01-01 00:00:00 UTC
当恰好给出十个参数时,这些参数的解释与上面的第二个调用序列相同
Time.utc(sec, min, hour, mday, month, year, dummy, dummy, dummy, dummy)
其中 dummy
参数被忽略
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Time.utc(*a) # => 0005-04-03 02:01:00 UTC
此形式对于从 Time.to_a
返回的 10 元素数组创建 Time
对象很有用
t = Time.new(2000, 1, 2, 3, 4, 5, 6) # => 2000-01-02 03:04:05 +000006 a = t.to_a # => [5, 4, 3, 2, 1, 2000, 0, 2, false, nil] Time.utc(*a) # => 2000-01-02 03:04:05 UTC
这两种形式的前六个参数是相同的,尽管顺序不同;这些公共参数的范围对于两种形式都是相同的; 请参阅上文。
如果参数的数量为八个、九个或大于十个,则会引发异常。
相关: Time.local
。
与 Time.utc
类似,除了返回的 Time
对象具有本地时区,而不是 UTC 时区
# With seven arguments. Time.local(0, 1, 2, 3, 4, 5, 6) # => 0000-01-02 03:04:05.000006 -0600 # With exactly ten arguments. Time.local(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) # => 0005-04-03 02:01:00 -0600
static VALUE time_s_mktime(int argc, VALUE *argv, VALUE klass) { struct vtm vtm; time_arg(argc, argv, &vtm); return time_localtime(time_new_timew(klass, timelocalw(&vtm))); }
与 Time.utc
类似,除了返回的 Time
对象具有本地时区,而不是 UTC 时区
# With seven arguments. Time.local(0, 1, 2, 3, 4, 5, 6) # => 0000-01-02 03:04:05.000006 -0600 # With exactly ten arguments. Time.local(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) # => 0005-04-03 02:01:00 -0600
根据给定的参数返回一个新的 Time
对象,默认情况下位于本地时区。
如果没有位置参数,则返回 Time.now
的值
Time.new # => 2021-04-24 17:27:46.0512465 -0500
如果有一个表示时间的字符串参数,则返回一个新的 Time
对象,该对象基于给定的参数,在本地时区中。
Time.new('2000-12-31 23:59:59.5') # => 2000-12-31 23:59:59.5 -0600 Time.new('2000-12-31 23:59:59.5 +0900') # => 2000-12-31 23:59:59.5 +0900 Time.new('2000-12-31 23:59:59.5', in: '+0900') # => 2000-12-31 23:59:59.5 +0900 Time.new('2000-12-31 23:59:59.5') # => 2000-12-31 23:59:59.5 -0600 Time.new('2000-12-31 23:59:59.56789', precision: 3) # => 2000-12-31 23:59:59.567 -0600
如果有一到六个参数,则返回一个新的 Time
对象,该对象基于给定的参数,在本地时区中。
Time.new(2000, 1, 2, 3, 4, 5) # => 2000-01-02 03:04:05 -0600
对于位置参数(zone
除外)
-
year
:年份,没有范围限制Time.new(999999999) # => 999999999-01-01 00:00:00 -0600 Time.new(-999999999) # => -999999999-01-01 00:00:00 -0600
-
month
:月份,范围 (1..12),或不区分大小写的 3 个字母的月份名称Time.new(2000, 1) # => 2000-01-01 00:00:00 -0600 Time.new(2000, 12) # => 2000-12-01 00:00:00 -0600 Time.new(2000, 'jan') # => 2000-01-01 00:00:00 -0600 Time.new(2000, 'JAN') # => 2000-01-01 00:00:00 -0600
-
mday
:月份中的天数,范围 (1..31)Time.new(2000, 1, 1) # => 2000-01-01 00:00:00 -0600 Time.new(2000, 1, 31) # => 2000-01-31 00:00:00 -0600
-
hour
:小时,范围 (0..23),如果min
、sec
和usec
为零,则为 24Time.new(2000, 1, 1, 0) # => 2000-01-01 00:00:00 -0600 Time.new(2000, 1, 1, 23) # => 2000-01-01 23:00:00 -0600 Time.new(2000, 1, 1, 24) # => 2000-01-02 00:00:00 -0600
-
min
:分钟,范围 (0..59)Time.new(2000, 1, 1, 0, 0) # => 2000-01-01 00:00:00 -0600 Time.new(2000, 1, 1, 0, 59) # => 2000-01-01 00:59:00 -0600
-
sec
:秒,范围 (0…61)Time.new(2000, 1, 1, 0, 0, 0) # => 2000-01-01 00:00:00 -0600 Time.new(2000, 1, 1, 0, 0, 59) # => 2000-01-01 00:00:59 -0600 Time.new(2000, 1, 1, 0, 0, 60) # => 2000-01-01 00:01:00 -0600
Time.new(2000, 1, 1, 0, 0, 59.5) # => 2000-12-31 23:59:59.5 +0900 Time.new(2000, 1, 1, 0, 0, 59.7r) # => 2000-12-31 23:59:59.7 +0900
这些值可以是
-
整数,如上所述。
-
可转换为整数的数值
Time.new(Float(0.0), Rational(1, 1), 1.0, 0.0, 0.0, 0.0) # => 0000-01-01 00:00:00 -0600
-
String
整数a = %w[0 1 1 0 0 0] # => ["0", "1", "1", "0", "0", "0"] Time.new(*a) # => 0000-01-01 00:00:00 -0600
当给定位置参数 zone
或关键字参数 in:
时,新的 Time
对象将处于指定的时区。有关参数 zone
的形式,请参见时区指定符。
Time.new(2000, 1, 1, 0, 0, 0, '+12:00') # => 2000-01-01 00:00:00 +1200 Time.new(2000, 1, 1, 0, 0, 0, in: '-12:00') # => 2000-01-01 00:00:00 -1200 Time.new(in: '-12:00') # => 2022-08-23 08:49:26.1941467 -1200
由于 in:
关键字参数只是提供了默认值,因此如果单字符串形式的第一个参数包含时区信息,则此关键字参数将被静默忽略。
Time.new('2000-01-01 00:00:00 +0100', in: '-0500').utc_offset # => 3600
-
precision
:子秒部分的最大有效位数,默认为 9。更多位数将被截断,就像Time
的其他操作一样。除非第一个参数是字符串,否则将被忽略。
# File ruby_3_4_1/timev.rb, line 434 def initialize(year = (now = true), mon = (str = year; nil), mday = nil, hour = nil, min = nil, sec = nil, zone = nil, in: nil, precision: 9) if zone if Primitive.arg!(:in) raise ArgumentError, "timezone argument given as positional and keyword arguments" end else zone = Primitive.arg!(:in) end if now return Primitive.time_init_now(zone) end if str and Primitive.time_init_parse(str, zone, precision) return self end Primitive.time_init_args(year, mon, mday, hour, min, sec, zone) end
根据给定的参数,以 UTC 时区返回一个新的 Time
对象。
当给出 1 到 7 个参数时,这些参数的解释与上面的第一个调用序列相同
Time.utc(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0)
示例
Time.utc(2000) # => 2000-01-01 00:00:00 UTC Time.utc(-2000) # => -2000-01-01 00:00:00 UTC
所需的参数 year
没有最小值和最大值。
对于可选参数
-
month
:月份,范围 (1..12),或不区分大小写的 3 个字母的月份名称Time.utc(2000, 1) # => 2000-01-01 00:00:00 UTC Time.utc(2000, 12) # => 2000-12-01 00:00:00 UTC Time.utc(2000, 'jan') # => 2000-01-01 00:00:00 UTC Time.utc(2000, 'JAN') # => 2000-01-01 00:00:00 UTC
-
mday
:月份中的天数,范围 (1..31)Time.utc(2000, 1, 1) # => 2000-01-01 00:00:00 UTC Time.utc(2000, 1, 31) # => 2000-01-31 00:00:00 UTC
-
hour
:小时,范围 (0..23),如果min
、sec
和usec
为零,则为 24Time.utc(2000, 1, 1, 0) # => 2000-01-01 00:00:00 UTC Time.utc(2000, 1, 1, 23) # => 2000-01-01 23:00:00 UTC Time.utc(2000, 1, 1, 24) # => 2000-01-02 00:00:00 UTC
-
min
:分钟,范围 (0..59)Time.utc(2000, 1, 1, 0, 0) # => 2000-01-01 00:00:00 UTC Time.utc(2000, 1, 1, 0, 59) # => 2000-01-01 00:59:00 UTC
-
sec
:秒,范围 (0..59),如果usec
为零,则为 60Time.utc(2000, 1, 1, 0, 0, 0) # => 2000-01-01 00:00:00 UTC Time.utc(2000, 1, 1, 0, 0, 59) # => 2000-01-01 00:00:59 UTC Time.utc(2000, 1, 1, 0, 0, 60) # => 2000-01-01 00:01:00 UTC
-
usec
:微秒,范围 (0..999999)Time.utc(2000, 1, 1, 0, 0, 0, 0) # => 2000-01-01 00:00:00 UTC Time.utc(2000, 1, 1, 0, 0, 0, 999999) # => 2000-01-01 00:00:00.999999 UTC
这些值可以是
-
整数,如上所述。
-
可转换为整数的数值
Time.utc(Float(0.0), Rational(1, 1), 1.0, 0.0, 0.0, 0.0, 0.0) # => 0000-01-01 00:00:00 UTC
-
String
整数a = %w[0 1 1 0 0 0 0 0] # => ["0", "1", "1", "0", "0", "0", "0", "0"] Time.utc(*a) # => 0000-01-01 00:00:00 UTC
当恰好给出十个参数时,这些参数的解释与上面的第二个调用序列相同
Time.utc(sec, min, hour, mday, month, year, dummy, dummy, dummy, dummy)
其中 dummy
参数被忽略
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Time.utc(*a) # => 0005-04-03 02:01:00 UTC
此形式对于从 Time.to_a
返回的 10 元素数组创建 Time
对象很有用
t = Time.new(2000, 1, 2, 3, 4, 5, 6) # => 2000-01-02 03:04:05 +000006 a = t.to_a # => [5, 4, 3, 2, 1, 2000, 0, 2, false, nil] Time.utc(*a) # => 2000-01-02 03:04:05 UTC
这两种形式的前六个参数是相同的,尽管顺序不同;这些公共参数的范围对于两种形式都是相同的; 请参阅上文。
如果参数的数量为八个、九个或大于十个,则会引发异常。
相关: Time.local
。
static VALUE time_s_mkutc(int argc, VALUE *argv, VALUE klass) { struct vtm vtm; time_arg(argc, argv, &vtm); return time_gmtime(time_new_timew(klass, timegmw(&vtm))); }
公共实例方法
返回一个新的 Time
对象,其值是 self
的数值和给定的 numeric
的总和。
t = Time.new(2000) # => 2000-01-01 00:00:00 -0600 t + (60 * 60 * 24) # => 2000-01-02 00:00:00 -0600 t + 0.5 # => 2000-01-01 00:00:00.5 -0600
相关链接:Time#-
。
static VALUE time_plus(VALUE time1, VALUE time2) { struct time_object *tobj; GetTimeval(time1, tobj); if (IsTimeval(time2)) { rb_raise(rb_eTypeError, "time + time?"); } return time_add(tobj, time1, time2, 1); }
当给定 numeric
时,返回一个新的 Time
对象,其值是 self
的数值与 numeric
的差值。
t = Time.new(2000) # => 2000-01-01 00:00:00 -0600 t - (60 * 60 * 24) # => 1999-12-31 00:00:00 -0600 t - 0.5 # => 1999-12-31 23:59:59.5 -0600
当给定 other_time
时,返回一个 Float
,其值是 self
和 other_time
的数值之差(以秒为单位)。
t - t # => 0.0
相关链接:Time#+
。
static VALUE time_minus(VALUE time1, VALUE time2) { struct time_object *tobj; GetTimeval(time1, tobj); if (IsTimeval(time2)) { struct time_object *tobj2; GetTimeval(time2, tobj2); return rb_Float(rb_time_unmagnify_to_float(wsub(tobj->timew, tobj2->timew))); } return time_add(tobj, time1, time2, -1); }
将 self
与 other_time
进行比较;返回
-
-1
,如果self
小于other_time
。 -
0
,如果self
等于other_time
。 -
1
,如果self
大于other_time
。 -
nil
,如果self
和other_time
不可比较。
示例
t = Time.now # => 2007-11-19 08:12:12 -0600 t2 = t + 2592000 # => 2007-12-19 08:12:12 -0600 t <=> t2 # => -1 t2 <=> t # => 1 t = Time.now # => 2007-11-19 08:13:38 -0600 t2 = t + 0.1 # => 2007-11-19 08:13:38 -0600 t.nsec # => 98222999 t2.nsec # => 198222999 t <=> t2 # => -1 t2 <=> t # => 1 t <=> t # => 0
static VALUE time_cmp(VALUE time1, VALUE time2) { struct time_object *tobj1, *tobj2; int n; GetTimeval(time1, tobj1); if (IsTimeval(time2)) { GetTimeval(time2, tobj2); n = wcmp(tobj1->timew, tobj2->timew); } else { return rb_invcmp(time1, time2); } if (n == 0) return INT2FIX(0); if (n > 0) return INT2FIX(1); return INT2FIX(-1); }
返回 self
的字符串表示形式,格式为 strftime('%a %b %e %T %Y')
或其简写版本 strftime('%c')
;请参见日期和时间格式。
t = Time.new(2000, 12, 31, 23, 59, 59, 0.5) t.ctime # => "Sun Dec 31 23:59:59 2000" t.strftime('%a %b %e %T %Y') # => "Sun Dec 31 23:59:59 2000" t.strftime('%c') # => "Sun Dec 31 23:59:59 2000"
相关链接:Time#to_s
,Time#inspect
t.inspect # => "2000-12-31 23:59:59.5 +000001" t.to_s # => "2000-12-31 23:59:59 +0000"
返回一个新的 Time
对象,其数值大于或等于 self
,并且其秒数被截断为精度 ndigits
。
t = Time.utc(2010, 3, 30, 5, 43, 25.123456789r) t # => 2010-03-30 05:43:25.123456789 UTC t.ceil # => 2010-03-30 05:43:26 UTC t.ceil(2) # => 2010-03-30 05:43:25.13 UTC t.ceil(4) # => 2010-03-30 05:43:25.1235 UTC t.ceil(6) # => 2010-03-30 05:43:25.123457 UTC t.ceil(8) # => 2010-03-30 05:43:25.12345679 UTC t.ceil(10) # => 2010-03-30 05:43:25.123456789 UTC t = Time.utc(1999, 12, 31, 23, 59, 59) t # => 1999-12-31 23:59:59 UTC (t + 0.4).ceil # => 2000-01-01 00:00:00 UTC (t + 0.9).ceil # => 2000-01-01 00:00:00 UTC (t + 1.4).ceil # => 2000-01-01 00:00:01 UTC (t + 1.9).ceil # => 2000-01-01 00:00:01 UTC
相关链接:Time#floor
,Time#round
。
static VALUE time_ceil(int argc, VALUE *argv, VALUE time) { VALUE ndigits, v, den; struct time_object *tobj; if (!rb_check_arity(argc, 0, 1) || NIL_P(ndigits = argv[0])) den = INT2FIX(1); else den = ndigits_denominator(ndigits); GetTimeval(time, tobj); v = w2v(rb_time_unmagnify(tobj->timew)); v = modv(v, den); if (!rb_equal(v, INT2FIX(0))) { v = subv(den, v); } return time_add(tobj, time, v, 1); }
返回 self
的字符串表示形式,格式为 strftime('%a %b %e %T %Y')
或其简写版本 strftime('%c')
;请参见日期和时间格式。
t = Time.new(2000, 12, 31, 23, 59, 59, 0.5) t.ctime # => "Sun Dec 31 23:59:59 2000" t.strftime('%a %b %e %T %Y') # => "Sun Dec 31 23:59:59 2000" t.strftime('%c') # => "Sun Dec 31 23:59:59 2000"
相关链接:Time#to_s
,Time#inspect
t.inspect # => "2000-12-31 23:59:59.5 +000001" t.to_s # => "2000-12-31 23:59:59 +0000"
static VALUE time_asctime(VALUE time) { return strftimev("%a %b %e %T %Y", time, rb_usascii_encoding()); }
返回 self
的月份中的整数日期,范围为 (1..31)。
t = Time.new(2000, 1, 2, 3, 4, 5, 6) # => 2000-01-02 03:04:05 +000006 t.mday # => 2
返回名称/值对的哈希值,用于模式匹配。可能的键是::year
、:month
、:day
、:yday
、:wday
、:hour
、:min
、:sec
、:subsec
、:dst
、:zone
。
可能的用法
t = Time.utc(2022, 10, 5, 21, 25, 30) if t in wday: 3, day: ..7 # uses deconstruct_keys underneath puts "first Wednesday of the month" end #=> prints "first Wednesday of the month" case t in year: ...2022 puts "too old" in month: ..9 puts "quarter 1-3" in wday: 1..5, month: puts "working day in month #{month}" end #=> prints "working day in month 10"
请注意,按模式解构也可以与类检查相结合
if t in Time(wday: 3, day: ..7) puts "first Wednesday of the month" end
static VALUE time_deconstruct_keys(VALUE time, VALUE keys) { struct time_object *tobj; VALUE h; long i; GetTimeval(time, tobj); MAKE_TM_ENSURE(time, tobj, tobj->vtm.yday != 0); if (NIL_P(keys)) { h = rb_hash_new_with_size(11); rb_hash_aset(h, sym_year, tobj->vtm.year); rb_hash_aset(h, sym_month, INT2FIX(tobj->vtm.mon)); rb_hash_aset(h, sym_day, INT2FIX(tobj->vtm.mday)); rb_hash_aset(h, sym_yday, INT2FIX(tobj->vtm.yday)); rb_hash_aset(h, sym_wday, INT2FIX(tobj->vtm.wday)); rb_hash_aset(h, sym_hour, INT2FIX(tobj->vtm.hour)); rb_hash_aset(h, sym_min, INT2FIX(tobj->vtm.min)); rb_hash_aset(h, sym_sec, INT2FIX(tobj->vtm.sec)); rb_hash_aset(h, sym_subsec, quov(w2v(wmod(tobj->timew, WINT2FIXWV(TIME_SCALE))), INT2FIX(TIME_SCALE))); rb_hash_aset(h, sym_dst, RBOOL(tobj->vtm.isdst)); rb_hash_aset(h, sym_zone, time_zone(time)); return h; } if (UNLIKELY(!RB_TYPE_P(keys, T_ARRAY))) { rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected Array or nil)", rb_obj_class(keys)); } h = rb_hash_new_with_size(RARRAY_LEN(keys)); for (i=0; i<RARRAY_LEN(keys); i++) { VALUE key = RARRAY_AREF(keys, i); if (sym_year == key) rb_hash_aset(h, key, tobj->vtm.year); if (sym_month == key) rb_hash_aset(h, key, INT2FIX(tobj->vtm.mon)); if (sym_day == key) rb_hash_aset(h, key, INT2FIX(tobj->vtm.mday)); if (sym_yday == key) rb_hash_aset(h, key, INT2FIX(tobj->vtm.yday)); if (sym_wday == key) rb_hash_aset(h, key, INT2FIX(tobj->vtm.wday)); if (sym_hour == key) rb_hash_aset(h, key, INT2FIX(tobj->vtm.hour)); if (sym_min == key) rb_hash_aset(h, key, INT2FIX(tobj->vtm.min)); if (sym_sec == key) rb_hash_aset(h, key, INT2FIX(tobj->vtm.sec)); if (sym_subsec == key) { rb_hash_aset(h, key, quov(w2v(wmod(tobj->timew, WINT2FIXWV(TIME_SCALE))), INT2FIX(TIME_SCALE))); } if (sym_dst == key) rb_hash_aset(h, key, RBOOL(tobj->vtm.isdst)); if (sym_zone == key) rb_hash_aset(h, key, time_zone(time)); } return h; }
如果 self
处于夏令时,则返回 true
,否则返回 false
。
t = Time.local(2000, 1, 1) # => 2000-01-01 00:00:00 -0600 t.zone # => "Central Standard Time" t.dst? # => false t = Time.local(2000, 7, 1) # => 2000-07-01 00:00:00 -0500 t.zone # => "Central Daylight Time" t.dst? # => true
如果 self
和 other_time
都是 Time
对象,并且具有完全相同的时间值,则返回 true
。
static VALUE time_eql(VALUE time1, VALUE time2) { struct time_object *tobj1, *tobj2; GetTimeval(time1, tobj1); if (IsTimeval(time2)) { GetTimeval(time2, tobj2); return rb_equal(w2v(tobj1->timew), w2v(tobj2->timew)); } return Qfalse; }
返回一个新的 Time
对象,其数值小于或等于 self
,并且其秒数被截断为精度 ndigits
。
t = Time.utc(2010, 3, 30, 5, 43, 25.123456789r) t # => 2010-03-30 05:43:25.123456789 UTC t.floor # => 2010-03-30 05:43:25 UTC t.floor(2) # => 2010-03-30 05:43:25.12 UTC t.floor(4) # => 2010-03-30 05:43:25.1234 UTC t.floor(6) # => 2010-03-30 05:43:25.123456 UTC t.floor(8) # => 2010-03-30 05:43:25.12345678 UTC t.floor(10) # => 2010-03-30 05:43:25.123456789 UTC t = Time.utc(1999, 12, 31, 23, 59, 59) t # => 1999-12-31 23:59:59 UTC (t + 0.4).floor # => 1999-12-31 23:59:59 UTC (t + 0.9).floor # => 1999-12-31 23:59:59 UTC (t + 1.4).floor # => 2000-01-01 00:00:00 UTC (t + 1.9).floor # => 2000-01-01 00:00:00 UTC
相关链接:Time#ceil
,Time#round
。
static VALUE time_floor(int argc, VALUE *argv, VALUE time) { VALUE ndigits, v, den; struct time_object *tobj; if (!rb_check_arity(argc, 0, 1) || NIL_P(ndigits = argv[0])) den = INT2FIX(1); else den = ndigits_denominator(ndigits); GetTimeval(time, tobj); v = w2v(rb_time_unmagnify(tobj->timew)); v = modv(v, den); return time_add(tobj, time, v, -1); }
如果 self
表示星期五,则返回 true
,否则返回 false
。
t = Time.utc(2000, 1, 7) # => 2000-01-07 00:00:00 UTC t.friday? # => true
相关链接:Time#saturday?
,Time#sunday?
,Time#monday?
。
static VALUE time_friday(VALUE time) { wday_p(5); }
返回一个新的 Time
对象,表示 self
的值转换为 UTC 时区。
local = Time.local(2000) # => 2000-01-01 00:00:00 -0600 local.utc? # => false utc = local.getutc # => 2000-01-01 06:00:00 UTC utc.utc? # => true utc == local # => true
static VALUE time_getgmtime(VALUE time) { return time_gmtime(time_dup(time)); }
返回一个新的 Time
对象,表示 self
的值转换为给定的时区;如果 zone
为 nil
,则使用本地时区。
t = Time.utc(2000) # => 2000-01-01 00:00:00 UTC t.getlocal # => 1999-12-31 18:00:00 -0600 t.getlocal('+12:00') # => 2000-01-01 12:00:00 +1200
有关参数 zone
的形式,请参见时区指定符。
static VALUE time_getlocaltime(int argc, VALUE *argv, VALUE time) { VALUE off; if (rb_check_arity(argc, 0, 1) && !NIL_P(off = argv[0])) { VALUE zone = off; if (maybe_tzobj_p(zone)) { VALUE t = time_dup(time); if (zone_localtime(off, t)) return t; } if (NIL_P(off = utc_offset_arg(off))) { off = zone; if (NIL_P(zone = find_timezone(time, off))) invalid_utc_offset(off); time = time_dup(time); if (!zone_localtime(zone, time)) invalid_utc_offset(off); return time; } else if (off == UTC_ZONE) { return time_gmtime(time_dup(time)); } validate_utc_offset(off); time = time_dup(time); time_set_utc_offset(time, off); return time_fixoff(time); } return time_localtime(time_dup(time)); }
返回一个新的 Time
对象,表示 self
的值转换为 UTC 时区。
local = Time.local(2000) # => 2000-01-01 00:00:00 -0600 local.utc? # => false utc = local.getutc # => 2000-01-01 06:00:00 UTC utc.utc? # => true utc == local # => true
如果 self
表示 UTC (GMT) 时间,则返回 true
。
now = Time.now # => 2022-08-18 10:24:13.5398485 -0500 now.utc? # => false utc = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC utc.utc? # => true
相关链接:Time.utc
。
返回 UTC 和 self
的时区之间的偏移量(以秒为单位)。
Time.utc(2000, 1, 1).utc_offset # => 0 Time.local(2000, 1, 1).utc_offset # => -21600 # -6*3600, or minus six hours.
返回 self
,已转换为 UTC 时区。
t = Time.new(2000) # => 2000-01-01 00:00:00 -0600 t.utc? # => false t.utc # => 2000-01-01 06:00:00 UTC t.utc? # => true
相关链接:Time#getutc
(返回一个新的转换后的 Time
对象)。
static VALUE time_gmtime(VALUE time) { struct time_object *tobj; struct vtm vtm; GetTimeval(time, tobj); if (TZMODE_UTC_P(tobj)) { if (tobj->vtm.tm_got) return time; } else { time_modify(time); } vtm.zone = str_utc; GMTIMEW(tobj->timew, &vtm); time_set_vtm(time, tobj, vtm); tobj->vtm.tm_got = 1; TZMODE_SET_UTC(tobj); return time; }
返回 UTC 和 self
的时区之间的偏移量(以秒为单位)。
Time.utc(2000, 1, 1).utc_offset # => 0 Time.local(2000, 1, 1).utc_offset # => -21600 # -6*3600, or minus six hours.
VALUE rb_time_utc_offset(VALUE time) { struct time_object *tobj; GetTimeval(time, tobj); if (TZMODE_UTC_P(tobj)) { return INT2FIX(0); } else { MAKE_TM(time, tobj); return tobj->vtm.utc_offset; } }
返回 self
的整数哈希码。
相关链接:Object#hash
。
static VALUE time_hash(VALUE time) { struct time_object *tobj; GetTimeval(time, tobj); return rb_hash(w2v(tobj->timew)); }
返回带有子秒的 self
的字符串表示形式。
t = Time.new(2000, 12, 31, 23, 59, 59, 0.5) t.inspect # => "2000-12-31 23:59:59.5 +000001"
相关链接:Time#ctime
,Time#to_s
t.ctime # => "Sun Dec 31 23:59:59 2000" t.to_s # => "2000-12-31 23:59:59 +0000"
static VALUE time_inspect(VALUE time) { struct time_object *tobj; VALUE str, subsec; GetTimeval(time, tobj); str = strftimev("%Y-%m-%d %H:%M:%S", time, rb_usascii_encoding()); subsec = w2v(wmod(tobj->timew, WINT2FIXWV(TIME_SCALE))); if (subsec == INT2FIX(0)) { } else if (FIXNUM_P(subsec) && FIX2LONG(subsec) < TIME_SCALE) { long len; rb_str_catf(str, ".%09ld", FIX2LONG(subsec)); for (len=RSTRING_LEN(str); RSTRING_PTR(str)[len-1] == '0' && len > 0; len--) ; rb_str_resize(str, len); } else { rb_str_cat_cstr(str, " "); subsec = quov(subsec, INT2FIX(TIME_SCALE)); rb_str_concat(str, rb_obj_as_string(subsec)); } if (TZMODE_UTC_P(tobj)) { rb_str_cat_cstr(str, " UTC"); } else { /* ?TODO: subsecond offset */ long off = NUM2LONG(rb_funcall(tobj->vtm.utc_offset, rb_intern("round"), 0)); char sign = (off < 0) ? (off = -off, '-') : '+'; int sec = off % 60; int min = (off /= 60) % 60; off /= 60; rb_str_catf(str, " %c%.2d%.2d", sign, (int)off, min); if (sec) rb_str_catf(str, "%.2d", sec); } return str; }
如果 self
处于夏令时,则返回 true
,否则返回 false
。
t = Time.local(2000, 1, 1) # => 2000-01-01 00:00:00 -0600 t.zone # => "Central Standard Time" t.dst? # => false t = Time.local(2000, 7, 1) # => 2000-07-01 00:00:00 -0500 t.zone # => "Central Daylight Time" t.dst? # => true
static VALUE time_isdst(VALUE time) { struct time_object *tobj; GetTimeval(time, tobj); MAKE_TM(time, tobj); if (tobj->vtm.isdst == VTM_ISDST_INITVAL) { rb_raise(rb_eRuntimeError, "isdst is not set yet"); } return RBOOL(tobj->vtm.isdst); }
返回一个字符串,该字符串表示由 XML Schema 定义的时间为 dateTime。
CCYY-MM-DDThh:mm:ssTZD CCYY-MM-DDThh:mm:ss.sssTZD
其中 TZD 为 Z 或 [+-]hh:mm。
如果 self 是 UTC 时间,则 Z 用作 TZD。否则,使用 [+-]hh:mm。
fraction_digits
指定用于小数秒的位数。其默认值为 0。
t = Time.now t.xmlschema # => "2011-10-05T22:26:12-04:00"
没有给定参数时
-
如果
self
是本地时间,则返回self
。 -
否则,返回用户本地时区中的新
Time
。t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC t.localtime # => 2000-01-01 14:15:01 -0600
如果给定参数 zone
,则返回通过将 self
转换为给定时区而创建的新 Time
对象。
t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC t.localtime("-09:00") # => 2000-01-01 11:15:01 -0900
有关参数 zone
的形式,请参见时区指定符。
static VALUE time_localtime_m(int argc, VALUE *argv, VALUE time) { VALUE off; if (rb_check_arity(argc, 0, 1) && !NIL_P(off = argv[0])) { return time_zonelocal(time, off); } return time_localtime(time); }
返回 self
的月份中的整数日期,范围为 (1..31)。
t = Time.new(2000, 1, 2, 3, 4, 5, 6) # => 2000-01-02 03:04:05 +000006 t.mday # => 2
相关链接:Time#year
,Time#hour
,Time#min
。
static VALUE time_mday(VALUE time) { struct time_object *tobj; GetTimeval(time, tobj); MAKE_TM(time, tobj); return INT2FIX(tobj->vtm.mday); }
返回 self
的一年中的整数月份数,范围为 (1..12)。
t = Time.new(2000, 1, 2, 3, 4, 5, 6) # => 2000-01-02 03:04:05 +000006 t.mon # => 1
相关链接:Time#year
,Time#hour
,Time#min
。
static VALUE time_mon(VALUE time) { struct time_object *tobj; GetTimeval(time, tobj); MAKE_TM(time, tobj); return INT2FIX(tobj->vtm.mon); }
如果 self
表示星期一,则返回 true
,否则返回 false
。
t = Time.utc(2000, 1, 3) # => 2000-01-03 00:00:00 UTC t.monday? # => true
相关链接:Time#tuesday?
,Time#wednesday?
,Time#thursday?
。
static VALUE time_monday(VALUE time) { wday_p(1); }
返回 self
的一年中的整数月份数,范围为 (1..12)。
t = Time.new(2000, 1, 2, 3, 4, 5, 6) # => 2000-01-02 03:04:05 +000006 t.mon # => 1
返回 self
的子秒部分中纳秒数,范围为 (0..999_999_999);较低位数字被截断,而不是四舍五入。
t = Time.now # => 2022-07-11 15:04:53.3219637 -0500 t.nsec # => 321963700
相关链接:Time#subsec
(返回精确的子秒)。
返回一个新的 Time
对象,其数值与 self
相同,并且其秒值四舍五入为精度 ndigits
。
t = Time.utc(2010, 3, 30, 5, 43, 25.123456789r) t # => 2010-03-30 05:43:25.123456789 UTC t.round # => 2010-03-30 05:43:25 UTC t.round(0) # => 2010-03-30 05:43:25 UTC t.round(1) # => 2010-03-30 05:43:25.1 UTC t.round(2) # => 2010-03-30 05:43:25.12 UTC t.round(3) # => 2010-03-30 05:43:25.123 UTC t.round(4) # => 2010-03-30 05:43:25.1235 UTC t = Time.utc(1999, 12,31, 23, 59, 59) t # => 1999-12-31 23:59:59 UTC (t + 0.4).round # => 1999-12-31 23:59:59 UTC (t + 0.49).round # => 1999-12-31 23:59:59 UTC (t + 0.5).round # => 2000-01-01 00:00:00 UTC (t + 1.4).round # => 2000-01-01 00:00:00 UTC (t + 1.49).round # => 2000-01-01 00:00:00 UTC (t + 1.5).round # => 2000-01-01 00:00:01 UTC
相关链接:Time#ceil
,Time#floor
。
static VALUE time_round(int argc, VALUE *argv, VALUE time) { VALUE ndigits, v, den; struct time_object *tobj; if (!rb_check_arity(argc, 0, 1) || NIL_P(ndigits = argv[0])) den = INT2FIX(1); else den = ndigits_denominator(ndigits); GetTimeval(time, tobj); v = w2v(rb_time_unmagnify(tobj->timew)); v = modv(v, den); if (lt(v, quov(den, INT2FIX(2)))) return time_add(tobj, time, v, -1); else return time_add(tobj, time, subv(den, v), 1); }
如果 self
表示星期六,则返回 true
,否则返回 false
。
t = Time.utc(2000, 1, 1) # => 2000-01-01 00:00:00 UTC t.saturday? # => true
相关链接:Time#sunday?
、Time#monday?
、Time#tuesday?
。
static VALUE time_saturday(VALUE time) { wday_p(6); }
返回 self
表示的分钟的秒数,范围为 (0..60) 的整数。
t = Time.new(2000, 1, 2, 3, 4, 5, 6) # => 2000-01-02 03:04:05 +000006 t.sec # => 5
注意:当存在闰秒时,秒数值可能为 60。
相关链接:Time#year
,Time#mon
,Time#min
。
static VALUE time_sec(VALUE time) { struct time_object *tobj; GetTimeval(time, tobj); MAKE_TM(time, tobj); return INT2FIX(tobj->vtm.sec); }
返回 self
的字符串表示形式,格式由给定的字符串 format
指定。请参阅 日期和时间的格式。
static VALUE time_strftime(VALUE time, VALUE format) { struct time_object *tobj; const char *fmt; long len; rb_encoding *enc; VALUE tmp; GetTimeval(time, tobj); MAKE_TM_ENSURE(time, tobj, tobj->vtm.yday != 0); StringValue(format); if (!rb_enc_str_asciicompat_p(format)) { rb_raise(rb_eArgError, "format should have ASCII compatible encoding"); } tmp = rb_str_tmp_frozen_acquire(format); fmt = RSTRING_PTR(tmp); len = RSTRING_LEN(tmp); enc = rb_enc_get(format); if (len == 0) { rb_warning("strftime called with empty format string"); return rb_enc_str_new(0, 0, enc); } else { VALUE str = rb_strftime_alloc(fmt, len, enc, time, &tobj->vtm, tobj->timew, TZMODE_UTC_P(tobj)); rb_str_tmp_frozen_release(format, tmp); if (!str) rb_raise(rb_eArgError, "invalid format: %"PRIsVALUE, format); return str; } }
返回 self
的精确亚秒数,类型为 Numeric
(Integer
或 Rational
)。
t = Time.now # => 2022-07-11 15:11:36.8490302 -0500 t.subsec # => (4245151/5000000)
如果亚秒数为零,则返回整数零。
t = Time.new(2000, 1, 1, 2, 3, 4) # => 2000-01-01 02:03:04 -0600 t.subsec # => 0
static VALUE time_subsec(VALUE time) { struct time_object *tobj; GetTimeval(time, tobj); return quov(w2v(wmod(tobj->timew, WINT2FIXWV(TIME_SCALE))), INT2FIX(TIME_SCALE)); }
如果 self
表示星期日,则返回 true
,否则返回 false
。
t = Time.utc(2000, 1, 2) # => 2000-01-02 00:00:00 UTC t.sunday? # => true
相关链接:Time#monday?
、Time#tuesday?
、Time#wednesday?
。
static VALUE time_sunday(VALUE time) { wday_p(0); }
如果 self
表示星期四,则返回 true
,否则返回 false
。
t = Time.utc(2000, 1, 6) # => 2000-01-06 00:00:00 UTC t.thursday? # => true
相关链接:Time#friday?
、Time#saturday?
、Time#sunday?
。
static VALUE time_thursday(VALUE time) { wday_p(4); }
返回一个包含 10 个元素的数组,表示 self
。
Time.utc(2000, 1, 1).to_a # => [0, 0, 0, 1, 1, 2000, 6, 1, false, "UTC"] # [sec, min, hour, day, mon, year, wday, yday, dst?, zone]
返回的数组适合用作 Time.utc
或 Time.local
的参数,以创建一个新的 Time
对象。
static VALUE time_to_a(VALUE time) { struct time_object *tobj; GetTimeval(time, tobj); MAKE_TM_ENSURE(time, tobj, tobj->vtm.yday != 0); return rb_ary_new3(10, INT2FIX(tobj->vtm.sec), INT2FIX(tobj->vtm.min), INT2FIX(tobj->vtm.hour), INT2FIX(tobj->vtm.mday), INT2FIX(tobj->vtm.mon), tobj->vtm.year, INT2FIX(tobj->vtm.wday), INT2FIX(tobj->vtm.yday), RBOOL(tobj->vtm.isdst), time_zone(time)); }
以 Float
数字形式返回 self
的值,即纪元秒数;包含亚秒数。
self
存储的值是一个 Rational,这意味着返回的值可能是近似值。
Time.utc(1970, 1, 1, 0, 0, 0).to_f # => 0.0 Time.utc(1970, 1, 1, 0, 0, 0, 999999).to_f # => 0.999999 Time.utc(1950, 1, 1, 0, 0, 0).to_f # => -631152000.0 Time.utc(1990, 1, 1, 0, 0, 0).to_f # => 631152000.0
static VALUE time_to_f(VALUE time) { struct time_object *tobj; GetTimeval(time, tobj); return rb_Float(rb_time_unmagnify_to_float(tobj->timew)); }
以整数形式返回 self
的值,即纪元秒数;亚秒数被截断(而不是四舍五入)。
Time.utc(1970, 1, 1, 0, 0, 0).to_i # => 0 Time.utc(1970, 1, 1, 0, 0, 0, 999999).to_i # => 0 Time.utc(1950, 1, 1, 0, 0, 0).to_i # => -631152000 Time.utc(1990, 1, 1, 0, 0, 0).to_i # => 631152000
static VALUE time_to_i(VALUE time) { struct time_object *tobj; GetTimeval(time, tobj); return w2v(wdiv(tobj->timew, WINT2FIXWV(TIME_SCALE))); }
返回 self
的字符串表示形式,不包含亚秒数。
t = Time.new(2000, 12, 31, 23, 59, 59, 0.5) t.to_s # => "2000-12-31 23:59:59 +0000"
相关链接:Time#ctime
、Time#inspect
。
t.ctime # => "Sun Dec 31 23:59:59 2000" t.inspect # => "2000-12-31 23:59:59.5 +000001"
static VALUE time_to_s(VALUE time) { struct time_object *tobj; GetTimeval(time, tobj); if (TZMODE_UTC_P(tobj)) return strftimev("%Y-%m-%d %H:%M:%S UTC", time, rb_usascii_encoding()); else return strftimev("%Y-%m-%d %H:%M:%S %z", time, rb_usascii_encoding()); }
如果 self
表示星期二,则返回 true
,否则返回 false
。
t = Time.utc(2000, 1, 4) # => 2000-01-04 00:00:00 UTC t.tuesday? # => true
相关链接:Time#wednesday?
、Time#thursday?
、Time#friday?
。
static VALUE time_tuesday(VALUE time) { wday_p(2); }
返回 self
的子秒部分中纳秒数,范围为 (0..999_999_999);较低位数字被截断,而不是四舍五入。
t = Time.now # => 2022-07-11 15:04:53.3219637 -0500 t.nsec # => 321963700
相关链接:Time#subsec
(返回精确的子秒)。
static VALUE time_nsec(VALUE time) { struct time_object *tobj; GetTimeval(time, tobj); return rb_to_int(w2v(wmulquoll(wmod(tobj->timew, WINT2WV(TIME_SCALE)), 1000000000, TIME_SCALE))); }
以整数形式返回 self
的值,即纪元秒数;亚秒数被截断(而不是四舍五入)。
Time.utc(1970, 1, 1, 0, 0, 0).to_i # => 0 Time.utc(1970, 1, 1, 0, 0, 0, 999999).to_i # => 0 Time.utc(1950, 1, 1, 0, 0, 0).to_i # => -631152000 Time.utc(1990, 1, 1, 0, 0, 0).to_i # => 631152000
返回 self
的亚秒部分中的微秒数,范围为 (0..999_999);较低位的数字被截断,而不是四舍五入。
t = Time.now # => 2022-07-11 14:59:47.5484697 -0500 t.usec # => 548469
相关链接:Time#subsec
(返回精确的子秒)。
static VALUE time_usec(VALUE time) { struct time_object *tobj; wideval_t w, q, r; GetTimeval(time, tobj); w = wmod(tobj->timew, WINT2WV(TIME_SCALE)); wmuldivmod(w, WINT2FIXWV(1000000), WINT2FIXWV(TIME_SCALE), &q, &r); return rb_to_int(w2v(q)); }
返回 self
的亚秒部分中的微秒数,范围为 (0..999_999);较低位的数字被截断,而不是四舍五入。
t = Time.now # => 2022-07-11 14:59:47.5484697 -0500 t.usec # => 548469
相关链接:Time#subsec
(返回精确的子秒)。
返回 self
,已转换为 UTC 时区。
t = Time.new(2000) # => 2000-01-01 00:00:00 -0600 t.utc? # => false t.utc # => 2000-01-01 06:00:00 UTC t.utc? # => true
相关链接:Time#getutc
(返回一个新的转换后的 Time
对象)。
如果 self
表示 UTC (GMT) 时间,则返回 true
。
now = Time.now # => 2022-08-18 10:24:13.5398485 -0500 now.utc? # => false utc = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC utc.utc? # => true
相关链接:Time.utc
。
static VALUE time_utc_p(VALUE time) { struct time_object *tobj; GetTimeval(time, tobj); return RBOOL(TZMODE_UTC_P(tobj)); }
返回 UTC 和 self
的时区之间的偏移量(以秒为单位)。
Time.utc(2000, 1, 1).utc_offset # => 0 Time.local(2000, 1, 1).utc_offset # => -21600 # -6*3600, or minus six hours.
返回 self
表示的星期几,范围为 (0..6) 的整数,其中星期日为零。
t = Time.new(2000, 1, 2, 3, 4, 5, 6) # => 2000-01-02 03:04:05 +000006 t.wday # => 0 t.sunday? # => true
相关链接:Time#year
,Time#hour
,Time#min
。
static VALUE time_wday(VALUE time) { struct time_object *tobj; GetTimeval(time, tobj); MAKE_TM_ENSURE(time, tobj, tobj->vtm.wday != VTM_WDAY_INITVAL); return INT2FIX((int)tobj->vtm.wday); }
如果 self
表示星期三,则返回 true
,否则返回 false
。
t = Time.utc(2000, 1, 5) # => 2000-01-05 00:00:00 UTC t.wednesday? # => true
相关链接:Time#thursday?
、Time#friday?
、Time#saturday?
。
static VALUE time_wednesday(VALUE time) { wday_p(3); }
返回一个字符串,该字符串表示由 XML Schema 定义的时间为 dateTime。
CCYY-MM-DDThh:mm:ssTZD CCYY-MM-DDThh:mm:ss.sssTZD
其中 TZD 为 Z 或 [+-]hh:mm。
如果 self 是 UTC 时间,则 Z 用作 TZD。否则,使用 [+-]hh:mm。
fraction_digits
指定用于小数秒的位数。其默认值为 0。
t = Time.now t.xmlschema # => "2011-10-05T22:26:12-04:00"
static VALUE time_xmlschema(int argc, VALUE *argv, VALUE time) { long fraction_digits = 0; rb_check_arity(argc, 0, 1); if (argc > 0) { fraction_digits = NUM2LONG(argv[0]); if (fraction_digits < 0) { fraction_digits = 0; } } struct time_object *tobj; GetTimeval(time, tobj); MAKE_TM(time, tobj); const long size_after_year = sizeof("-MM-DDTHH:MM:SS+ZH:ZM") + fraction_digits + (fraction_digits > 0); VALUE str; char *ptr; # define fill_digits_long(len, prec, n) \ for (int fill_it = 1, written = snprintf(ptr, len, "%0*ld", prec, n); \ fill_it; ptr += written, fill_it = 0) if (FIXNUM_P(tobj->vtm.year)) { long year = FIX2LONG(tobj->vtm.year); int year_width = (year < 0) + rb_strlen_lit("YYYY"); int w = (year >= -9999 && year <= 9999 ? year_width : (year < 0) + (int)DECIMAL_SIZE_OF(year)); str = rb_usascii_str_new(0, w + size_after_year); ptr = RSTRING_PTR(str); fill_digits_long(w + 1, year_width, year) { if (year >= -9999 && year <= 9999) { RUBY_ASSERT(written == year_width); } else { RUBY_ASSERT(written >= year_width); RUBY_ASSERT(written <= w); } } } else { str = rb_int2str(tobj->vtm.year, 10); rb_str_modify_expand(str, size_after_year); ptr = RSTRING_END(str); } # define fill_2(c, n) (*ptr++ = c, *ptr++ = '0' + (n) / 10, *ptr++ = '0' + (n) % 10) fill_2('-', tobj->vtm.mon); fill_2('-', tobj->vtm.mday); fill_2('T', tobj->vtm.hour); fill_2(':', tobj->vtm.min); fill_2(':', tobj->vtm.sec); if (fraction_digits > 0) { VALUE subsecx = tobj->vtm.subsecx; long subsec; int digits = -1; *ptr++ = '.'; if (fraction_digits <= TIME_SCALE_NUMDIGITS) { digits = TIME_SCALE_NUMDIGITS - (int)fraction_digits; } else { long w = fraction_digits - TIME_SCALE_NUMDIGITS; /* > 0 */ subsecx = mulv(subsecx, rb_int_positive_pow(10, (unsigned long)w)); if (!RB_INTEGER_TYPE_P(subsecx)) { /* maybe Rational */ subsecx = rb_Integer(subsecx); } if (FIXNUM_P(subsecx)) digits = 0; } if (digits >= 0 && fraction_digits < INT_MAX) { subsec = NUM2LONG(subsecx); if (digits > 0) subsec /= (long)pow(10, digits); fill_digits_long(fraction_digits + 1, (int)fraction_digits, subsec) { RUBY_ASSERT(written == (int)fraction_digits); } } else { subsecx = rb_int2str(subsecx, 10); long len = RSTRING_LEN(subsecx); if (fraction_digits > len) { memset(ptr, '0', fraction_digits - len); } else { len = fraction_digits; } ptr += fraction_digits; memcpy(ptr - len, RSTRING_PTR(subsecx), len); } } if (TZMODE_UTC_P(tobj)) { *ptr = 'Z'; ptr++; } else { long offset = NUM2LONG(rb_time_utc_offset(time)); char sign = offset < 0 ? '-' : '+'; if (offset < 0) offset = -offset; offset /= 60; fill_2(sign, offset / 60); fill_2(':', offset % 60); } const char *const start = RSTRING_PTR(str); rb_str_set_len(str, ptr - start); // We could skip coderange scanning as we know it's full ASCII. return str; }
返回 self
表示的当年的第几天,范围为 (1..366) 的整数。
Time.new(2000, 1, 1).yday # => 1 Time.new(2000, 12, 31).yday # => 366
static VALUE time_yday(VALUE time) { struct time_object *tobj; GetTimeval(time, tobj); MAKE_TM_ENSURE(time, tobj, tobj->vtm.yday != 0); return INT2FIX(tobj->vtm.yday); }
返回 self
表示的时区的字符串名称。
Time.utc(2000, 1, 1).zone # => "UTC" Time.new(2000, 1, 1).zone # => "Central Standard Time"
static VALUE time_zone(VALUE time) { struct time_object *tobj; VALUE zone; GetTimeval(time, tobj); MAKE_TM(time, tobj); if (TZMODE_UTC_P(tobj)) { return rb_usascii_str_new_cstr("UTC"); } zone = tobj->vtm.zone; if (NIL_P(zone)) return Qnil; if (RB_TYPE_P(zone, T_STRING)) zone = rb_str_dup(zone); return zone; }