class Time
公共类方法
将 date
解析为 RFC 2616 定义的 HTTP-date 并将其转换为 Time
对象。
如果 date
不符合 RFC 2616 或 Time
类无法表示指定的日期,则会引发 ArgumentError。
有关此格式的更多信息,请参阅 httpdate
。
require 'time' Time.httpdate("Thu, 06 Oct 2011 02:26:12 GMT") #=> 2011-10-06 02:26:12 UTC
您必须 require ‘time’ 才能使用此方法。
# File time.rb, line 569 def httpdate(date) if date.match?(/\A\s* (?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\x20 (\d{2})\x20 (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\x20 (\d{4})\x20 (\d{2}):(\d{2}):(\d{2})\x20 GMT \s*\z/ix) self.rfc2822(date).utc elsif /\A\s* (?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday),\x20 (\d\d)-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(\d\d)\x20 (\d\d):(\d\d):(\d\d)\x20 GMT \s*\z/ix =~ date year = $3.to_i if year < 50 year += 2000 else year += 1900 end self.utc(year, $2, $1.to_i, $4.to_i, $5.to_i, $6.to_i) elsif /\A\s* (?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\x20 (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\x20 (\d\d|\x20\d)\x20 (\d\d):(\d\d):(\d\d)\x20 (\d{4}) \s*\z/ix =~ date self.utc($6.to_i, MonthValue[$1.upcase], $2.to_i, $3.to_i, $4.to_i, $5.to_i) else raise ArgumentError.new("not RFC 2616 compliant date: #{date.inspect}") end end
接收 Time
的字符串表示形式,并尝试使用启发式方法解析它。
此方法**不**作为验证器。如果输入字符串不严格匹配有效格式,您可能会得到一个神秘的结果。应尽可能考虑使用 Time.strptime
而不是此方法。
require 'time' Time.parse("2010-10-31") #=> 2010-10-31 00:00:00 -0500
日期中任何缺失的部分都会根据当前日期进行推断。
require 'time' # assuming the current date is "2011-10-31" Time.parse("12:00") #=> 2011-10-31 12:00:00 -0500
我们可以通过传递第二个对象来更改用于推断缺失元素的日期,该对象可以响应 mon、day 和 year,例如 Date、Time
或 DateTime。我们也可以使用我们自己的对象。
require 'time' class MyDate attr_reader :mon, :day, :year def initialize(mon, day, year) @mon, @day, @year = mon, day, year end end d = Date.parse("2010-10-28") t = Time.parse("2010-10-29") dt = DateTime.parse("2010-10-30") md = MyDate.new(10,31,2010) Time.parse("12:00", d) #=> 2010-10-28 12:00:00 -0500 Time.parse("12:00", t) #=> 2010-10-29 12:00:00 -0500 Time.parse("12:00", dt) #=> 2010-10-30 12:00:00 -0500 Time.parse("12:00", md) #=> 2010-10-31 12:00:00 -0500
如果给出了代码块,则 date
中描述的年份将由代码块转换。这是专门为处理两位数年份而设计的。例如,如果您想将 70 之前的所有两位数年份视为 2000+ 年,您可以这样写
require 'time' Time.parse("01-10-31") {|year| year + (year < 70 ? 2000 : 1900)} #=> 2001-10-31 00:00:00 -0500 Time.parse("70-10-31") {|year| year + (year < 70 ? 2000 : 1900)} #=> 1970-10-31 00:00:00 -0500
如果给定时间的较高部分损坏或缺失,则会用 now
的相应部分填充。对于较低的部分,如果损坏或缺失,则假定最小值为(1 或 0)。例如
require 'time' # Suppose it is "Thu Nov 29 14:33:20 2001" now and # your time zone is EST which is GMT-5. now = Time.parse("Thu Nov 29 14:33:20 2001") Time.parse("16:30", now) #=> 2001-11-29 16:30:00 -0500 Time.parse("7/23", now) #=> 2001-07-23 00:00:00 -0500 Time.parse("Aug 31", now) #=> 2001-08-31 00:00:00 -0500 Time.parse("Aug 2000", now) #=> 2000-08-01 00:00:00 -0500
由于世界各地本地定义的时区缩写之间存在大量冲突,因此此方法并非旨在理解所有这些缩写。例如,缩写“CST”被各种用作
-06:00 in America/Chicago, -05:00 in America/Havana, +08:00 in Asia/Harbin, +09:30 in Australia/Darwin, +10:30 in Australia/Adelaide, etc.
基于此事实,此方法仅按名称顺序理解 RFC 822 中描述的时区缩写和系统时区。(即,RFC 822 中的定义会覆盖系统时区定义。)系统时区取自 Time.local(year, 1, 1).zone
和 Time.local(year, 7, 1).zone
。如果提取的时区缩写与它们中的任何一个都不匹配,则会忽略它,并将给定时间视为本地时间。
如果 Date._parse 无法从 date
中提取信息,或者 Time
类无法表示指定的日期,则会引发 ArgumentError。
此方法可用作其他解析方法的故障保护,例如
Time.rfc2822(date) rescue Time.parse(date) Time.httpdate(date) rescue Time.parse(date) Time.xmlschema(date) rescue Time.parse(date)
但应检查 Time.parse
的失败情况。
您必须 require ‘time’ 才能使用此方法。
# File time.rb, line 382 def parse(date, now=self.now) comp = !block_given? d = Date._parse(date, comp) year = d[:year] year = yield(year) if year && !comp make_time(date, year, d[:yday], d[:mon], d[:mday], d[:hour], d[:min], d[:sec], d[:sec_fraction], d[:zone], now) end
将 date
解析为 RFC 2822 定义的日期时间并将其转换为 Time
对象。该格式与 RFC 822 定义并由 RFC 1123 更新的日期格式相同。
如果 date
不符合 RFC 2822 或 Time
类无法表示指定的日期,则会引发 ArgumentError。
有关此格式的更多信息,请参阅 rfc2822
。
require 'time' Time.rfc2822("Wed, 05 Oct 2011 22:26:12 -0400") #=> 2010-10-05 22:26:12 -0400
您必须 require ‘time’ 才能使用此方法。
# File time.rb, line 511 def rfc2822(date) if /\A\s* (?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s*,\s*)? (\d{1,2})\s+ (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+ (\d{2,})\s+ (\d{2})\s* :\s*(\d{2}) (?:\s*:\s*(\d\d))?\s+ ([+-]\d{4}| UT|GMT|EST|EDT|CST|CDT|MST|MDT|PST|PDT|[A-IK-Z])/ix =~ date # Since RFC 2822 permit comments, the regexp has no right anchor. day = $1.to_i mon = MonthValue[$2.upcase] year = $3.to_i short_year_p = $3.length <= 3 hour = $4.to_i min = $5.to_i sec = $6 ? $6.to_i : 0 zone = $7 if short_year_p # following year completion is compliant with RFC 2822. year = if year < 50 2000 + year else 1900 + year end end off = zone_offset(zone) year, mon, day, hour, min, sec = apply_offset(year, mon, day, hour, min, sec, off) t = self.utc(year, mon, day, hour, min, sec) force_zone!(t, zone, off) t else raise ArgumentError.new("not RFC 2822 compliant date: #{date.inspect}") end end
与 parse
的工作方式类似,但不是使用启发式方法来检测输入字符串的格式,而是提供第二个参数来描述字符串的格式。
如果日期或格式无效,则会引发 ArgumentError。
如果给出了代码块,则 date
中描述的年份将由代码块转换。例如
Time.strptime(...) {|y| y < 100 ? (y >= 69 ? y + 1900 : y + 2000) : y}
以下是格式化选项的列表
- %a
-
工作日名称的缩写(“Sun”)
- %A
-
工作日的全名(“Sunday”)
- %b
-
月份名称的缩写(“Jan”)
- %B
-
月份的全名(“January”)
- %c
-
首选的本地日期和时间表示
- %C
-
世纪(2009 年为 20)
- %d
-
月份中的日期(01..31)
- %D
-
日期(%m/%d/%y)
- %e
-
月份中的日期,用空格填充( 1..31)
- %F
-
等效于 %Y-%m-%d(ISO 8601 日期格式)
- %g
-
商业年的最后两位数字
- %G
-
根据 ISO-8601 的基于周的年份(第 1 周从星期一开始,包括 1 月 4 日)
- %h
-
等效于 %b
- %H
-
一天中的小时,24 小时制(00..23)
- %I
-
一天中的小时,12 小时制(01..12)
- %j
-
一年中的日期(001..366)
- %k
-
小时,24 小时制,用空格填充( 0..23)
- %l
-
小时,12 小时制,用空格填充( 0..12)
- %L
-
秒的毫秒(000..999)
- %m
-
一年中的月份(01..12)
- %M
-
小时中的分钟(00..59)
- %n
-
换行符 (n)
- %N
-
秒的小数位数
- %p
-
子午线指示符(“AM”或“PM”)
- %P
-
子午线指示符(“am”或“pm”)
- %r
-
时间,12 小时制(与 %I:%M:%S %p 相同)
- %R
-
时间,24 小时制(%H:%M)
- %s
-
自 1970-01-01 00:00:00 UTC 以来的秒数。
- %S
-
分钟中的秒数(00..60)
- %t
-
制表符 (t)
- %T
-
时间,24 小时制(%H:%M:%S)
- %u
-
工作日作为十进制数,星期一为 1。(1..7)
- %U
-
当前年份的周数,从第一个星期日作为第一周的第一天开始(00..53)
- %v
-
VMS 日期(%e-%b-%Y)
- %V
-
根据 ISO 8601 的年份周数(01..53)
- %W
-
当前年份的周数,从第一个星期一作为第一周的第一天开始(00..53)
- %w
-
星期几(星期日为 0,0..6)
- %x
-
仅表示日期的首选表示形式,没有时间
- %X
-
仅表示时间的首选表示形式,没有日期
- %y
-
没有世纪的年份(00..99)
- %Y
-
可能包含世纪的年份(如果提供)
- %z
-
时区作为与 UTC 的小时偏移量(例如 +0900)
- %Z
-
时区名称
- %%
-
文字“%”字符
- %+
-
date(1) (%a %b %e %H:%M:%S %Z %Y)
require 'time' Time.strptime("2000-10-31", "%Y-%m-%d") #=> 2000-10-31 00:00:00 -0500
您必须 require ‘time’ 才能使用此方法。
# File time.rb, line 459 def strptime(date, format, now=self.now) d = Date._strptime(date, format) raise ArgumentError, "invalid date or strptime format - '#{date}' '#{format}'" unless d if seconds = d[:seconds] if sec_fraction = d[:sec_fraction] usec = sec_fraction * 1000000 usec *= -1 if seconds < 0 else usec = 0 end t = Time.at(seconds, usec) if zone = d[:zone] force_zone!(t, zone) end else year = d[:year] year = yield(year) if year && block_given? yday = d[:yday] if (d[:cwyear] && !year) || ((d[:cwday] || d[:cweek]) && !(d[:mon] && d[:mday])) # make_time doesn't deal with cwyear/cwday/cweek return Date.strptime(date, format).to_time end if (d[:wnum0] || d[:wnum1]) && !yday && !(d[:mon] && d[:mday]) yday = Date.strptime(date, format).yday end t = make_time(date, year, yday, d[:mon], d[:mday], d[:hour], d[:min], d[:sec], d[:sec_fraction], d[:zone], now) end t end
将 time
解析为 XML Schema 定义的 dateTime,并将其转换为 Time
对象。该格式是 ISO 8601 定义的格式的受限版本。
如果 time
不符合该格式,或者 Time
类无法表示指定的时间,则会引发 ArgumentError。
有关此格式的更多信息,请参阅 xmlschema
。
require 'time' Time.xmlschema("2011-10-05T22:26:12-04:00") #=> 2011-10-05 22:26:12-04:00
您必须 require ‘time’ 才能使用此方法。
# File time.rb, line 623 def xmlschema(time) if /\A\s* (-?\d+)-(\d\d)-(\d\d) T (\d\d):(\d\d):(\d\d) (\.\d+)? (Z|[+-]\d\d(?::?\d\d)?)? \s*\z/ix =~ time year = $1.to_i mon = $2.to_i day = $3.to_i hour = $4.to_i min = $5.to_i sec = $6.to_i usec = 0 if $7 usec = Rational($7) * 1000000 end if $8 zone = $8 off = zone_offset(zone) year, mon, day, hour, min, sec = apply_offset(year, mon, day, hour, min, sec, off) t = self.utc(year, mon, day, hour, min, sec, usec) force_zone!(t, zone, off) t else self.local(year, mon, day, hour, min, sec, usec) end else raise ArgumentError.new("invalid xmlschema format: #{time.inspect}") end end
返回指定时区与 UTC 之间的秒数差。
包括分钟的数字时区(如 -10:00
或 +1330
)以及更简单的仅包含小时的时区(如 -10
或 +13
)都可以使用。
还支持 ZoneOffset 中列出的文本时区。
如果时区与上述任何一个都不匹配,zone_offset
将检查本地时区(包括和不包括潜在的夏令时更改)是否与 zone
匹配。为 year
指定一个值将更改用于查找本地时区的年份。
如果 zone_offset
无法确定偏移量,则将返回 nil。
require 'time' Time.zone_offset("EST") #=> -18000
您必须 require ‘time’ 才能使用此方法。
# File time.rb, line 83 def zone_offset(zone, year=self.now.year) off = nil zone = zone.upcase if /\A([+-])(\d\d)(:?)(\d\d)(?:\3(\d\d))?\z/ =~ zone off = ($1 == '-' ? -1 : 1) * (($2.to_i * 60 + $4.to_i) * 60 + $5.to_i) elsif zone.match?(/\A[+-]\d\d\z/) off = zone.to_i * 3600 elsif ZoneOffset.include?(zone) off = ZoneOffset[zone] * 3600 elsif ((t = self.local(year, 1, 1)).zone.upcase == zone rescue false) off = t.utc_offset elsif ((t = self.local(year, 7, 1)).zone.upcase == zone rescue false) off = t.utc_offset end off end
公共实例方法
返回一个字符串,该字符串表示为 RFC 2616 定义的 HTTP-date 的 RFC 1123 日期的时间
day-of-week, DD month-name CCYY hh:mm:ss GMT
请注意,结果始终为 UTC (GMT)。
require 'time' t = Time.now t.httpdate # => "Thu, 06 Oct 2011 02:26:12 GMT"
您必须 require ‘time’ 才能使用此方法。
# File time.rb, line 695 def httpdate getutc.strftime('%a, %d %b %Y %T GMT') end
返回一个字符串,该字符串表示为 RFC 2822 定义的日期时间
day-of-week, DD month-name CCYY hh:mm:ss zone
其中 zone 为 [+-]hhmm。
如果 self
是 UTC 时间,则使用 -0000 作为 zone。
require 'time' t = Time.now t.rfc2822 # => "Wed, 05 Oct 2011 22:26:12 -0400"
您必须 require ‘time’ 才能使用此方法。
# File time.rb, line 675 def rfc2822 strftime('%a, %d %b %Y %T ') << (utc? ? '-0000' : strftime('%z')) end
返回一个字符串,该字符串表示为 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。
require 'time' t = Time.now t.iso8601 # => "2011-10-05T22:26:12-04:00"
您必须 require ‘time’ 才能使用此方法。
# File time.rb, line 721 def xmlschema(fraction_digits=0) fraction_digits = fraction_digits.to_i s = strftime("%FT%T") if fraction_digits > 0 s << strftime(".%#{fraction_digits}N") end s << (utc? ? 'Z' : strftime("%:z")) end