- #
- A
- B
- C
- D
- E
- F
- I
- M
- N
- P
- R
- S
- T
- U
- Z
常量
COMMON_YEAR_DAYS_IN_MONTH | = | [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] |
DATE_FORMATS | = | { db: "%Y-%m-%d %H:%M:%S", inspect: "%Y-%m-%d %H:%M:%S.%9N %z", number: "%Y%m%d%H%M%S", nsec: "%Y%m%d%H%M%S%9N", usec: "%Y%m%d%H%M%S%6N", time: "%H:%M", short: "%d %b %H:%M", long: "%B %d, %Y %H:%M", long_ordinal: lambda { |time| day_format = ActiveSupport::Inflector.ordinalize(time.day) time.strftime("%B #{day_format}, %Y %H:%M") }, rfc822: lambda { |time| offset_format = time.formatted_offset(false) time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}") }, rfc2822: lambda { |time| time.rfc2822 }, iso8601: lambda { |time| time.iso8601 } } |
属性
[RW] | zone_default |
类公共方法
===(other) 链接
覆盖 case 等于方法,以便它对 ActiveSupport::TimeWithZone
实例返回 true
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 18 def ===(other) super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone)) end
at_with_coercion(time_or_number, *args) 链接
在 Time.at
上添加额外的行为,以便使用单个参数调用时可以使用 ActiveSupport::TimeWithZone
和 DateTime
实例
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 45 def at_with_coercion(time_or_number, *args) if args.empty? if time_or_number.is_a?(ActiveSupport::TimeWithZone) at_without_coercion(time_or_number.to_r).getlocal elsif time_or_number.is_a?(DateTime) at_without_coercion(time_or_number.to_f).getlocal else at_without_coercion(time_or_number) end else at_without_coercion(time_or_number, *args) end end
current() 链接
当设置了 Time.zone
或 config.time_zone
时,返回 Time.zone.now
,否则只返回 Time.now
。
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 39 def current ::Time.zone ? ::Time.zone.now : ::Time.now end
days_in_month(month, year = current.year) 链接
返回给定月份的天数。如果没有指定年份,它将使用当前年份。
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 24 def days_in_month(month, year = current.year) if month == 2 && ::Date.gregorian_leap?(year) 29 else COMMON_YEAR_DAYS_IN_MONTH[month] end end
days_in_year(year = current.year) 链接
返回给定年份的天数。如果没有指定年份,它将使用当前年份。
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 34 def days_in_year(year = current.year) days_in_month(2, year) + 337 end
find_zone(time_zone) 链接
返回与提供的时区匹配的 TimeZone 实例。接受 Time.zone=
支持的任何格式的时区。对于无效的时区返回 nil
。
Time.find_zone "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
Time.find_zone "NOT-A-TIMEZONE" # => nil
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/zones.rb, line 93 def find_zone(time_zone) find_zone!(time_zone) rescue nil end
find_zone!(time_zone) 链接
返回与提供的时区匹配的 TimeZone 实例。接受 Time.zone=
支持的任何格式的时区。对于无效的时区引发 ArgumentError
。
Time.find_zone! "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
Time.find_zone! "EST" # => #<ActiveSupport::TimeZone @name="EST" ...>
Time.find_zone! -5.hours # => #<ActiveSupport::TimeZone @name="Bogota" ...>
Time.find_zone! nil # => nil
Time.find_zone! false # => false
Time.find_zone! "NOT-A-TIMEZONE" # => ArgumentError: Invalid Timezone: NOT-A-TIMEZONE
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/zones.rb, line 81 def find_zone!(time_zone) return time_zone unless time_zone ActiveSupport::TimeZone[time_zone] || raise(ArgumentError, "Invalid Timezone: #{time_zone}") end
rfc3339(str) 链接
从 RFC 3339 字符串创建 Time
实例。
Time.rfc3339('1999-12-31T14:00:00-10:00') # => 2000-01-01 00:00:00 -1000
如果时间或偏移量组件丢失,则会引发 ArgumentError
。
Time.rfc3339('1999-12-31') # => ArgumentError: invalid date
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 69 def rfc3339(str) parts = Date._rfc3339(str) raise ArgumentError, "invalid date" if parts.empty? Time.new( parts.fetch(:year), parts.fetch(:mon), parts.fetch(:mday), parts.fetch(:hour), parts.fetch(:min), parts.fetch(:sec) + parts.fetch(:sec_fraction, 0), parts.fetch(:offset) ) end
use_zone(time_zone) 链接
允许在提供的块中本地覆盖 Time.zone
;完成后将 Time.zone
重置为现有值。
class ApplicationController < ActionController::Base
around_action :set_time_zone
private
def set_time_zone
Time.use_zone(current_user.timezone) { yield }
end
end
注意:这不会影响已创建的任何 ActiveSupport::TimeWithZone
对象,例如,在块之前读取的任何模型时间戳属性将保留在应用程序的默认时区中。
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/zones.rb, line 61 def use_zone(time_zone) new_zone = find_zone!(time_zone) begin old_zone, ::Time.zone = ::Time.zone, new_zone yield ensure ::Time.zone = old_zone end end
zone() 链接
返回当前请求的 TimeZone,如果已设置(通过 Time.zone=
)。如果未为当前请求设置 Time.zone
,则返回 config.time_zone
中指定的 TimeZone。
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/zones.rb, line 14 def zone ::ActiveSupport::IsolatedExecutionState[:time_zone] || zone_default end
zone=(time_zone) 链接
将 Time.zone
设置为当前请求/线程的 TimeZone 对象。
此方法接受以下任何一项
-
Rails TimeZone 对象。
-
Rails TimeZone 对象的标识符(例如,“东部时间(美国和加拿大)”,
-5.hours
)。 -
TZInfo::Timezone
对象。 -
TZInfo::Timezone
对象的标识符(例如,“America/New_York”)。
以下是如何在每个请求的基础上设置 Time.zone
并完成请求时重置它的示例。current_user.time_zone
只需返回一个字符串,标识用户的首选时区
class ApplicationController < ActionController::Base
around_action :set_time_zone
def set_time_zone
if logged_in?
Time.use_zone(current_user.time_zone) { yield }
else
yield
end
end
end
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/zones.rb, line 41 def zone=(time_zone) ::ActiveSupport::IsolatedExecutionState[:time_zone] = find_zone!(time_zone) end
实例公共方法
acts_like_time?() 链接
像 Time 类一样鸭子类型。见 Object#acts_like?
。
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/acts_like.rb, line 7 def acts_like_time? true end
advance(options) 链接
使用 Date
为年、月和日提供精确的 Time
计算,根据儒略历。options
参数接受一个包含以下任何键的哈希::years
、:months
、:weeks
、:days
、:hours
、:minutes
、:seconds
。
Time.new(2015, 8, 1, 14, 35, 0).advance(seconds: 1) # => 2015-08-01 14:35:01 -0700
Time.new(2015, 8, 1, 14, 35, 0).advance(minutes: 1) # => 2015-08-01 14:36:00 -0700
Time.new(2015, 8, 1, 14, 35, 0).advance(hours: 1) # => 2015-08-01 15:35:00 -0700
Time.new(2015, 8, 1, 14, 35, 0).advance(days: 1) # => 2015-08-02 14:35:00 -0700
Time.new(2015, 8, 1, 14, 35, 0).advance(weeks: 1) # => 2015-08-08 14:35:00 -0700
就像 Date#advance
一样,增量按时间单位从大到小的顺序应用。这种顺序可能会影响月底的结果。
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 194 def advance(options) unless options[:weeks].nil? options[:weeks], partial_weeks = options[:weeks].divmod(1) options[:days] = options.fetch(:days, 0) + 7 * partial_weeks end unless options[:days].nil? options[:days], partial_days = options[:days].divmod(1) options[:hours] = options.fetch(:hours, 0) + 24 * partial_days end d = to_date.gregorian.advance(options) time_advanced_by_date = change(year: d.year, month: d.month, day: d.day) seconds_to_advance = \ options.fetch(:seconds, 0) + options.fetch(:minutes, 0) * 60 + options.fetch(:hours, 0) * 3600 if seconds_to_advance.zero? time_advanced_by_date else time_advanced_by_date.since(seconds_to_advance) end end
ago(seconds) 链接
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 220 def ago(seconds) since(-seconds) end
beginning_of_day() 链接
返回一个新的 Time
对象,表示一天的开始(0:00)
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 238 def beginning_of_day change(hour: 0) end
beginning_of_hour() 链接
返回一个新的 Time
对象,表示一小时的开始(x:00)
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 267 def beginning_of_hour change(min: 0) end
beginning_of_minute() 链接
返回一个新的 Time
对象,表示一分钟的开始(x:xx:00)
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 283 def beginning_of_minute change(sec: 0) end
change(options) 链接
返回一个新的 Time
对象,其中一个或多个元素已根据 options
参数更改。时间选项(:hour
、:min
、:sec
、:usec
、:nsec
)是级联重置的,因此,如果只传递小时,则分钟、秒、微妙和纳秒将设置为 0。如果传递了小时和分钟,则秒、微妙和纳秒将设置为 0。options
参数接受包含以下任意键的哈希::year
、:month
、:day
、:hour
、:min
、:sec
、:usec
、:nsec
、:offset
。请传递 :usec
或 :nsec
,不要同时传递两者。
Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 123 def change(options) new_year = options.fetch(:year, year) new_month = options.fetch(:month, month) new_day = options.fetch(:day, day) new_hour = options.fetch(:hour, hour) new_min = options.fetch(:min, options[:hour] ? 0 : min) new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec) new_offset = options.fetch(:offset, nil) if new_nsec = options[:nsec] raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec] new_usec = Rational(new_nsec, 1000) else new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000)) end raise ArgumentError, "argument out of range" if new_usec >= 1000000 new_sec += Rational(new_usec, 1000000) if new_offset ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset) elsif utc? ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec) elsif zone.respond_to?(:utc_to_local) new_time = ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, zone) # Some versions of Ruby have a bug where Time.new with a zone object and # fractional seconds will end up with a broken utc_offset. # This is fixed in Ruby 3.3.1 and 3.2.4 unless new_time.utc_offset.integer? new_time += 0 end # When there are two occurrences of a nominal time due to DST ending, # `Time.new` chooses the first chronological occurrence (the one with a # larger UTC offset). However, for `change`, we want to choose the # occurrence that matches this time's UTC offset. # # If the new time's UTC offset is larger than this time's UTC offset, the # new time might be a first chronological occurrence. So we add the offset # difference to fast-forward the new time, and check if the result has the # desired UTC offset (i.e. is the second chronological occurrence). offset_difference = new_time.utc_offset - utc_offset if offset_difference > 0 && (new_time_2 = new_time + offset_difference).utc_offset == utc_offset new_time_2 else new_time end elsif zone ::Time.local(new_sec, new_min, new_hour, new_day, new_month, new_year, nil, nil, isdst, nil) else ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset) end end
compare_with_coercion(other) 链接
在 Time#<=>
上添加了额外的行为,以便可以将 DateTime
和 ActiveSupport::TimeWithZone
实例与 Time
对象按时间顺序进行比较
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 329 def compare_with_coercion(other) # we're avoiding Time#to_datetime and Time#to_time because they're expensive if other.class == Time compare_without_coercion(other) elsif other.is_a?(Time) # also avoid ActiveSupport::TimeWithZone#to_time before Rails 8.0 if other.respond_to?(:comparable_time) compare_without_coercion(other.comparable_time) else compare_without_coercion(other.to_time) end else to_datetime <=> other end end
end_of_day() 链接
返回一个新的 Time
对象,表示一天的结束,23:59:59.999999
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 256 def end_of_day change( hour: 23, min: 59, sec: 59, usec: Rational(999999999, 1000) ) end
end_of_hour() 链接
返回一个新的 Time
对象,表示一小时的结束,x:59:59.999999
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 273 def end_of_hour change( min: 59, sec: 59, usec: Rational(999999999, 1000) ) end
end_of_minute() 链接
返回一个新的 Time
对象,表示一分钟的结束,x:xx:59.999999
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 289 def end_of_minute change( sec: 59, usec: Rational(999999999, 1000) ) end
eql_with_coercion(other) 链接
在 Time#eql?
上添加了额外的行为,以便可以将 ActiveSupport::TimeWithZone
实例与等效的 Time
对象进行 eql? 比较
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 349 def eql_with_coercion(other) # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do eql? comparison other = other.comparable_time if other.respond_to?(:comparable_time) eql_without_coercion(other) end
formatted_offset(colon = true, alternate_utc_string = nil) 链接
返回时区与 UTC 之间偏移量的格式化字符串,或者如果时区已经是 UTC,则返回备用字符串。
Time.local(2000).formatted_offset # => "-06:00"
Time.local(2000).formatted_offset(false) # => "-0600"
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/conversions.rb, line 69 def formatted_offset(colon = true, alternate_utc_string = nil) utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon) end
middle_of_day() 链接
返回一个新的 Time
对象,表示一天的中间(12:00)
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 246 def middle_of_day change(hour: 12) end
minus_with_coercion(other) 链接
Time#-
也可用于确定两个 Time
实例之间的秒数。我们在上面添加了额外的行为,以便将 ActiveSupport::TimeWithZone
实例强制转换为 Time#-
可以识别的值。
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 320 def minus_with_coercion(other) other = other.comparable_time if other.respond_to?(:comparable_time) other.is_a?(DateTime) ? to_f - other.to_f : minus_without_coercion(other) end
next_day(days = 1) 链接
返回一个新的时间对象,表示未来指定天数的时间。
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 363 def next_day(days = 1) advance(days: days) end
next_month(months = 1) 链接
返回一个新的时间对象,表示未来指定月数的时间。
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 373 def next_month(months = 1) advance(months: months) end
next_year(years = 1) 链接
返回一个新的时间对象,表示未来指定年数的时间。
源代码: 显示 | 在 GitHub 上
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 383 def next_year(years = 1) advance(years: years) end
prev_day(days = 1) 链接
返回指定天数之前的时间。
来源:显示 | GitHub 上查看
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 358 def prev_day(days = 1) advance(days: -days) end
prev_month(months = 1) 链接
返回指定月份之前的时间。
来源:显示 | GitHub 上查看
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 368 def prev_month(months = 1) advance(months: -months) end
prev_year(years = 1) 链接
返回指定年份之前的时间。
来源:显示 | GitHub 上查看
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 378 def prev_year(years = 1) advance(years: -years) end
sec_fraction() 链接
将秒的尾数以 Rational
形式返回。
Time.new(2012, 8, 29, 0, 0, 0.5).sec_fraction # => (1/2)
来源:显示 | GitHub 上查看
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 107 def sec_fraction subsec end
seconds_since_midnight() 链接
返回从 00:00:00 开始的秒数。
Time.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0.0
Time.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296.0
Time.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399.0
来源:显示 | GitHub 上查看
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 91 def seconds_since_midnight to_i - change(hour: 0).to_i + (usec / 1.0e+6) end
seconds_until_end_of_day() 链接
返回到 23:59:59 的秒数。
Time.new(2012, 8, 29, 0, 0, 0).seconds_until_end_of_day # => 86399
Time.new(2012, 8, 29, 12, 34, 56).seconds_until_end_of_day # => 41103
Time.new(2012, 8, 29, 23, 59, 59).seconds_until_end_of_day # => 0
来源:显示 | GitHub 上查看
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 100 def seconds_until_end_of_day end_of_day.to_i - to_i end
since(seconds) 链接
返回一个新的 Time
对象,该对象表示自实例时间起经过指定秒数的时间。
来源:显示 | GitHub 上查看
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 225 def since(seconds) self + seconds rescue TypeError result = to_datetime.since(seconds) ActiveSupport.deprecator.warn( "Passing an instance of #{seconds.class} to #{self.class}#since is deprecated. This behavior will raise " \ "a `TypeError` in Rails 8.1." ) result end
to_fs(format = :default) 链接
将时间转换为格式化的字符串。有关内置格式,请参见 DATE_FORMATS
。
该方法的别名为 to_formatted_s
。
time = Time.now # => 2007-01-18 06:10:17 -06:00
time.to_fs(:time) # => "06:10"
time.to_formatted_s(:time) # => "06:10"
time.to_fs(:db) # => "2007-01-18 06:10:17"
time.to_fs(:number) # => "20070118061017"
time.to_fs(:short) # => "18 Jan 06:10"
time.to_fs(:long) # => "January 18, 2007 06:10"
time.to_fs(:long_ordinal) # => "January 18th, 2007 06:10"
time.to_fs(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
time.to_fs(:rfc2822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
time.to_fs(:iso8601) # => "2007-01-18T06:10:17-06:00"
向 to_fs
添加自定义时间格式
您可以向 Time::DATE_FORMATS
哈希添加自定义格式。将格式名称用作哈希键,将 strftime 字符串或接受时间参数的 Proc 实例用作值。
# config/initializers/time_formats.rb
Time::DATE_FORMATS[:month_and_year] = '%B %Y'
Time::DATE_FORMATS[:short_ordinal] = ->(time) { time.strftime("%B #{time.day.ordinalize}") }
来源:显示 | GitHub 上查看
# File activesupport/lib/active_support/core_ext/time/conversions.rb, line 55 def to_fs(format = :default) if formatter = DATE_FORMATS[format] formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter) else to_s end end
to_time() 链接
根据 ActiveSupport.to_time_preserves_timezone
设置,要么返回 self
,要么返回本地系统时区中的时间。
来源:显示 | GitHub 上查看
# File activesupport/lib/active_support/core_ext/time/compatibility.rb, line 13 def to_time preserve_timezone ? self : getlocal end