класс ActiveSupport::TimeWithZone
Класс, подобный Time, который может представлять время в любой часовой зоне. Необходим, потому что стандартные экземпляры Ruby Time ограничены UTC и системной ENV['TZ'] зоной.
Вам не нужно создавать экземпляры TimeWithZone напрямую через new. Вместо этого используйте методы local, parse, at и now для экземпляров TimeZone, и in_time_zone для экземпляров Time и DateTime.
Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
Time.zone.local(2007, 2, 10, 15, 30, 45) # => Sat, 10 Feb 2007 15:30:45.000000000 EST -05:00
Time.zone.parse('2007-02-10 15:30:45') # => Sat, 10 Feb 2007 15:30:45.000000000 EST -05:00
Time.zone.at(1171139445) # => Sat, 10 Feb 2007 15:30:45.000000000 EST -05:00
Time.zone.now # => Sun, 18 May 2008 13:07:55.754107581 EDT -04:00
Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone # => Sat, 10 Feb 2007 15:30:45.000000000 EST -05:00
См. Time и TimeZone для дополнительной документации по этим методам.
Экземпляры TimeWithZone реализуют тот же API, что и экземпляры Ruby Time, поэтому экземпляры Time и TimeWithZone взаимозаменяемы.
t = Time.zone.now # => Sun, 18 May 2008 13:27:25.031505668 EDT -04:00 t.hour # => 13 t.dst? # => true t.utc_offset # => -14400 t.zone # => "EDT" t.to_s(:rfc822) # => "Sun, 18 May 2008 13:27:25 -0400" t + 1.day # => Mon, 19 May 2008 13:27:25.031505668 EDT -04:00 t.beginning_of_year # => Tue, 01 Jan 2008 00:00:00.000000000 EST -05:00 t > Time.utc(1999) # => true t.is_a?(Time) # => true t.is_a?(ActiveSupport::TimeWithZone) # => true
Константы
- PRECISIONS
- СЕКУНДЫ_В_СУТКАХ
Атрибуты
Публичные Классовые Методы
# File activesupport/lib/active_support/time_with_zone.rb, line 42 def self.name "Time" end
Отчет о имени класса как 'Time' для предотвращения проверки типов.
# File activesupport/lib/active_support/time_with_zone.rb, line 52 def initialize(utc_time, time_zone, local_time = nil, period = nil) @utc = utc_time ? transfer_time_values_to_utc_constructor(utc_time) : nil @time_zone, @time = time_zone, local_time @period = @utc ? period : get_period_and_ensure_valid_local_time(period) end
Общедоступные методы экземпляров
# File activesupport/lib/active_support/time_with_zone.rb, line 292
def +(other)
if duration_of_variable_length?(other)
method_missing(:+, other)
else
result = utc.acts_like?(:date) ? utc.since(other) : utc + other rescue utc.since(other)
result.in_time_zone(time_zone)
end
end Добавляет интервал времени к текущему времени объекта и возвращает это значение в виде нового объекта TimeWithZone.
Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)' now = Time.zone.now # => Sun, 02 Nov 2014 01:26:28.725182881 EDT -04:00 now + 1000 # => Sun, 02 Nov 2014 01:43:08.725182881 EDT -04:00
Если мы добавляем Duration переменной длительности (т.е., годы, месяцы, дни), переходим вперёд от time, иначе переходим вперёд от utc для точности при пересечении границ DST.
Например, время + 24.часа продвинет время точно на 24 часа, а время + 1.день продвинет время на 23-25 часов, в зависимости от дня.
now + 24.hours # => Mon, 03 Nov 2014 00:26:28.725182881 EST -05:00 now + 1.day # => Mon, 03 Nov 2014 01:26:28.725182881 EST -05:00
# File activesupport/lib/active_support/time_with_zone.rb, line 327
def -(other)
if other.acts_like?(:time)
to_time - other.to_time
elsif duration_of_variable_length?(other)
method_missing(:-, other)
else
result = utc.acts_like?(:date) ? utc.ago(other) : utc - other rescue utc.ago(other)
result.in_time_zone(time_zone)
end
end Вычитает интервал времени и возвращает новый объект TimeWithZone, если значение `acts_like?` time. В противном случае вернёт Float разницы между двумя временами, представляющей разницу между текущим временем объекта и other временем.
Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)' now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28.725182881 EST -05:00 now - 1000 # => Mon, 03 Nov 2014 00:09:48.725182881 EST -05:00
Если вычитается Duration переменной длительности (т.е., годы, месяцы, дни), переходим назад от time, иначе переходим назад от utc для точности при пересечении границ DST.
Например, время - 24.часа вычтет точно 24 часа, а время - 1.день вычтет 23-25 часов, в зависимости от дня.
now - 24.hours # => Sun, 02 Nov 2014 01:26:28.725182881 EDT -04:00 now - 1.day # => Sun, 02 Nov 2014 00:26:28.725182881 EDT -04:00
Если объект TimeWithZone и другое значение действуют как Time, будет возвращено Float.
Time.zone.now - 1.day.ago # => 86399.999967
# File activesupport/lib/active_support/time_with_zone.rb, line 225 def <=>(other) utc <=> other end
Для сравнений используйте время в UTC.
# File activesupport/lib/active_support/time_with_zone.rb, line 488 def acts_like_time? true end
Для того, чтобы self acts_like?(:time).
# File activesupport/lib/active_support/time_with_zone.rb, line 416
def advance(options)
# If we're advancing a value of variable length (i.e., years, weeks, months, days), advance from #time,
# otherwise advance from #utc, for accuracy when moving across DST boundaries
if options.values_at(:years, :weeks, :months, :days).any?
method_missing(:advance, options)
else
utc.advance(options).in_time_zone(time_zone)
end
end Использует Date для предоставления точных расчётов Time для лет, месяцев и дней согласно пролептическому григорианскому календарю. Результат возвращается как новый объект TimeWithZone.
Параметр options принимает хеш с любыми из этих ключей: :years, :months, :weeks, :days, :hours, :minutes, :seconds.
Если продвижение происходит на значение переменной длительности (т.е., годы, недели, месяцы, дни), переходим вперёд от time, иначе переходим вперёд от utc для точности при пересечении границ DST.
Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)' now = Time.zone.now # => Sun, 02 Nov 2014 01:26:28.558049687 EDT -04:00 now.advance(seconds: 1) # => Sun, 02 Nov 2014 01:26:29.558049687 EDT -04:00 now.advance(minutes: 1) # => Sun, 02 Nov 2014 01:27:28.558049687 EDT -04:00 now.advance(hours: 1) # => Sun, 02 Nov 2014 01:26:28.558049687 EST -05:00 now.advance(days: 1) # => Mon, 03 Nov 2014 01:26:28.558049687 EST -05:00 now.advance(weeks: 1) # => Sun, 09 Nov 2014 01:26:28.558049687 EST -05:00 now.advance(months: 1) # => Tue, 02 Dec 2014 01:26:28.558049687 EST -05:00 now.advance(years: 1) # => Mon, 02 Nov 2015 01:26:28.558049687 EST -05:00
# File activesupport/lib/active_support/time_with_zone.rb, line 355 def ago(other) since(-other) end
Вычитает интервал времени из текущего времени объекта и возвращает результат в виде нового объекта TimeWithZone.
Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)' now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28.725182881 EST -05:00 now.ago(1000) # => Mon, 03 Nov 2014 00:09:48.725182881 EST -05:00
Если мы вычитаем Duration переменной длительности (т.е., годы, месяцы, дни), переходим назад от time, иначе переходим назад от utc для точности при пересечении границ DST.
Например, time.ago(24.hours) переместит время назад точно на 24 часа, а time.ago(1.day) переместит время назад на 23-25 часов, в зависимости от дня.
now.ago(24.hours) # => Sun, 02 Nov 2014 01:26:28.725182881 EDT -04:00 now.ago(1.day) # => Sun, 02 Nov 2014 00:26:28.725182881 EDT -04:00
# File activesupport/lib/active_support/time_with_zone.rb, line 167
def as_json(options = nil)
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
xmlschema(ActiveSupport::JSON::Encoding.time_precision)
else
%(#{time.strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
end
end Преобразует время в строку для кодирования JSON. По умолчанию используется формат ISO 8601. Вы можете получить формат %Y/%m/%d %H:%M:%S +смещение, установив ActiveSupport::JSON::Encoding.use_standard_json_time_format на false.
# With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
Time.utc(2005,2,1,15,15,10).in_time_zone("Hawaii").to_json
# => "2005-02-01T05:15:10.000-10:00"
# With ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
Time.utc(2005,2,1,15,15,10).in_time_zone("Hawaii").to_json
# => "2005/02/01 05:15:10 -1000"
# File activesupport/lib/active_support/time_with_zone.rb, line 233 def between?(min, max) utc.between?(min, max) end
Возвращает true, если текущее время объекта находится между указанным min и max временем.
# File activesupport/lib/active_support/time_with_zone.rb, line 499 def blank? false end
Экземпляр ActiveSupport::TimeWithZone никогда не является пустым
# File activesupport/lib/active_support/time_with_zone.rb, line 376
def change(options)
if options[:zone] && options[:offset]
raise ArgumentError, "Can't change both :offset and :zone at the same time: #{options.inspect}"
end
new_time = time.change(options)
if options[:zone]
new_zone = ::Time.find_zone(options[:zone])
elsif options[:offset]
new_zone = ::Time.find_zone(new_time.utc_offset)
end
new_zone ||= time_zone
periods = new_zone.periods_for_local(new_time)
self.class.new(nil, new_zone, new_time, periods.include?(period) ? period : nil)
end Возвращает новый ActiveSupport::TimeWithZone, где один или несколько элементов были изменены в соответствии с параметром options. Параметры времени (:hour, :min, :sec, :usec, :nsec) изменяются каскадно, поэтому если передан только час, то минута, секунда, микросекунда и наносекунда устанавливаются в 0. Если передан час и минута, то секунда, микросекунда и наносекунда устанавливаются в 0. Параметр options принимает хеш с любыми из этих ключей: :year, :month, :day, :hour, :min, :sec, :usec, :nsec, :offset, :zone. Передайте либо :usec или :nsec, а не оба значения. Аналогично, передайте либо :zone или :offset, а не оба значения.
t = Time.zone.now # => Fri, 14 Apr 2017 11:45:15.116992711 EST -05:00 t.change(year: 2020) # => Tue, 14 Apr 2020 11:45:15.116992711 EST -05:00 t.change(hour: 12) # => Fri, 14 Apr 2017 12:00:00.116992711 EST -05:00 t.change(min: 30) # => Fri, 14 Apr 2017 11:30:00.116992711 EST -05:00 t.change(offset: "-10:00") # => Fri, 14 Apr 2017 11:45:15.116992711 HST -10:00 t.change(zone: "Hawaii") # => Fri, 14 Apr 2017 11:45:15.116992711 HST -10:00
# File activesupport/lib/active_support/time_with_zone.rb, line 95 def dst? period.dst? end
Возвращает true, если текущее время находится в летнем времени DST для указанной зоны времени.
Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
Time.zone.parse("2012-5-30").dst? # => true
Time.zone.parse("2012-11-30").dst? # => false
# File activesupport/lib/active_support/time_with_zone.rb, line 268 def eql?(other) other.eql?(utc) end
Возвращает true если other равно текущему объекту.
# File activesupport/lib/active_support/time_with_zone.rb, line 126 def formatted_offset(colon = true, alternate_utc_string = nil) utc? && alternate_utc_string || TimeZone.seconds_to_utc_offset(utc_offset, colon) end
Возвращает отформатированную строку смещения от UTC или альтернативную строку, если зона времени уже UTC.
Time.zone = 'Eastern Time (US & Canada)' # => "Eastern Time (US & Canada)" Time.zone.now.formatted_offset(true) # => "-05:00" Time.zone.now.formatted_offset(false) # => "-0500" Time.zone = 'UTC' # => "UTC" Time.zone.now.formatted_offset(true, "0") # => "0"
# File activesupport/lib/active_support/time_with_zone.rb, line 503 def freeze # preload instance variables before freezing period; utc; time; to_datetime; to_time super end
# File activesupport/lib/active_support/time_with_zone.rb, line 263 def future? utc.future? end
Возвращает true, если текущее время объекта находится в будущем.
# File activesupport/lib/active_support/time_with_zone.rb, line 272 def hash utc.hash end
# File activesupport/lib/active_support/time_with_zone.rb, line 188 def httpdate utc.httpdate end
Возвращает строку с датой и временем объекта в формате, используемом в HTTP-запросах.
Time.zone.now.httpdate # => "Tue, 01 Jan 2013 04:39:43 GMT"
# File activesupport/lib/active_support/time_with_zone.rb, line 78 def in_time_zone(new_zone = ::Time.zone) return self if time_zone == new_zone utc.in_time_zone(new_zone) end
Возвращает одновременное время в Time.zone, или в указанной зоне.
# File activesupport/lib/active_support/time_with_zone.rb, line 141
def inspect
"#{time.strftime('%a, %d %b %Y %H:%M:%S.%9N')} #{zone} #{formatted_offset}"
end Возвращает строку с датой, временем, зоной и смещением от UTC объекта.
Time.zone.now.inspect # => "Thu, 04 Dec 2014 11:00:25.624541392 EST -05:00"
# File activesupport/lib/active_support/time_with_zone.rb, line 493 def is_a?(klass) klass == ::Time || super end
Предположим, что мы — Time, чтобы предотвратить проверку типов.
# File activesupport/lib/active_support/time_with_zone.rb, line 84 def localtime(utc_offset = nil) utc.getlocal(utc_offset) end
Возвращает экземпляр Time одновременного времени в часовом поясе системы.
# File activesupport/lib/active_support/time_with_zone.rb, line 509 def marshal_dump [utc, time_zone.name, time] end
# File activesupport/lib/active_support/time_with_zone.rb, line 513 def marshal_load(variables) initialize(variables[0].utc, ::Time.find_zone(variables[1]), variables[2].utc) end
# File activesupport/lib/active_support/time_with_zone.rb, line 534 def method_missing(sym, *args, &block) wrap_with_time_zone time.__send__(sym, *args, &block) rescue NoMethodError => e raise e, e.message.sub(time.inspect, inspect), e.backtrace end
Отправляет отсутствующий метод экземпляру time, и оборачивает результат в новый TimeWithZone с существующим time_zone.
# File activesupport/lib/active_support/time_with_zone.rb, line 238 def past? utc.past? end
Возвращает true, если текущее время объекта находится в прошлом.
# File activesupport/lib/active_support/time_with_zone.rb, line 73 def period @period ||= time_zone.period_for_utc(@utc) end
Возвращает базовый TZInfo::TimezonePeriod.
# File activesupport/lib/active_support/time_with_zone.rb, line 519 def respond_to?(sym, include_priv = false) # ensure that we're not going to throw and rescue from NoMethodError in method_missing which is slow return false if sym.to_sym == :to_str super end
respond_to_missing? не вызывается в некоторых случаях, таких как при преобразовании типов с помощью Kernel#String
# File activesupport/lib/active_support/time_with_zone.rb, line 527 def respond_to_missing?(sym, include_priv) return false if sym.to_sym == :acts_like_date? time.respond_to?(sym, include_priv) end
Обеспечение того, что прокси-класс отвечает на все методы, к которым отвечает базовый экземпляр времени.
# File activesupport/lib/active_support/time_with_zone.rb, line 196 def rfc2822 to_s(:rfc822) end
Возвращает строку с датой и временем объекта в формате RFC 2822.
Time.zone.now.rfc2822 # => "Tue, 01 Jan 2013 04:51:39 +0000"
# File activesupport/lib/active_support/time_with_zone.rb, line 219
def strftime(format)
format = format.gsub(/((?:\A|[^%])(?:%%)*)%Z/, "\\1#{zone}")
getlocal(utc_offset).strftime(format)
end Заменяет директиву %Z на +zone перед передачей в Time#strftime, чтобы информация о часовом поясе была правильной.
# File activesupport/lib/active_support/time_with_zone.rb, line 59 def time @time ||= incorporate_utc_offset(@utc, utc_offset) end
Возвращает экземпляр Time, представляющий время в time_zone.
# File activesupport/lib/active_support/time_with_zone.rb, line 439 def to_a [time.sec, time.min, time.hour, time.day, time.mon, time.year, time.wday, time.yday, dst?, zone] end
Возвращает Array частей Time в последовательности [секунды, минуты, часы, день, месяц, год, день недели, день года, DST?, часовой пояс].
now = Time.zone.now # => Tue, 18 Aug 2015 02:29:27.485278555 UTC +00:00 now.to_a # => [27, 29, 2, 18, 8, 2015, 2, 230, false, "UTC"]
# File activesupport/lib/active_support/time_with_zone.rb, line 472 def to_datetime @to_datetime ||= utc.to_datetime.new_offset(Rational(utc_offset, 86_400)) end
Возвращает экземпляр DateTime со смещением часового пояса от UTC.
Time.zone.now.to_datetime # => Tue, 18 Aug 2015 02:32:20 +0000
Time.current.in_time_zone('Hawaii').to_datetime # => Mon, 17 Aug 2015 16:32:20 -1000
# File activesupport/lib/active_support/time_with_zone.rb, line 447 def to_f utc.to_f end
Возвращает дату и время объекта как число с плавающей запятой, количество секунд, прошедших с эпохи (1 января 1970 года 00:00 UTC).
Time.zone.now.to_f # => 1417709320.285418
# File activesupport/lib/active_support/time_with_zone.rb, line 455 def to_i utc.to_i end
Возвращает дату и время объекта как целое число, количество секунд, прошедших с эпохи (1 января 1970 года 00:00 UTC).
Time.zone.now.to_i # => 1417709320
# File activesupport/lib/active_support/time_with_zone.rb, line 464 def to_r utc.to_r end
Возвращает дату и время объекта как рациональное число, количество секунд, прошедших с эпохи (1 января 1970 года 00:00 UTC).
Time.zone.now.to_r # => (708854548642709/500000)
# File activesupport/lib/active_support/time_with_zone.rb, line 206
def to_s(format = :default)
if format == :db
utc.to_s(format)
elsif formatter = ::Time::DATE_FORMATS[format]
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
else
"#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby Time#to_s format
end
end Возвращает строку даты и времени объекта. Принимает необязательный format:
-
:default- значение по умолчанию, имитирует формат RubyTime#to_s. -
:db- формат выводит время в UTC :db time. См.Time#to_formatted_s(:db). -
Любой ключ в
Time::DATE_FORMATSможет быть использован. См. active_support/core_ext/time/conversions.rb.
# File activesupport/lib/active_support/time_with_zone.rb, line 479
def to_time
if preserve_timezone
@to_time_with_instance_offset ||= getlocal(utc_offset)
else
@to_time_with_system_offset ||= getlocal
end
end Возвращает экземпляр Time, либо с тем же смещением UTC, что и self, или в локальном часовом поясе системы в зависимости от настройки ActiveSupport.to_time_preserves_timezone.
# File activesupport/lib/active_support/time_with_zone.rb, line 244 def today? time.today? end
Возвращает true, если текущее время объекта попадает в текущий день.
# File activesupport/lib/active_support/time_with_zone.rb, line 250 def tomorrow? time.tomorrow? end
Возвращает true, если текущее время объекта попадает в следующий день (завтра).
# File activesupport/lib/active_support/time_with_zone.rb, line 64 def utc @utc ||= incorporate_utc_offset(@time, -utc_offset) end
Возвращает экземпляр Time с одновременным временем в часовом поясе UTC.
# File activesupport/lib/active_support/time_with_zone.rb, line 106 def utc? zone == "UTC" || zone == "UCT" end
Возвращает true, если текущий часовой пояс установлен на UTC.
Time.zone = 'UTC' # => 'UTC' Time.zone.now.utc? # => true Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)' Time.zone.now.utc? # => false
# File activesupport/lib/active_support/time_with_zone.rb, line 112 def utc_offset period.observed_utc_offset end
Возвращает смещение от текущего времени до UTC в секундах.
# File activesupport/lib/active_support/time_with_zone.rb, line 149
def xmlschema(fraction_digits = 0)
"#{time.strftime(PRECISIONS[fraction_digits.to_i])}#{formatted_offset(true, 'Z')}"
end Возвращает строку даты и времени объекта в формате ISO 8601.
Time.zone.now.xmlschema # => "2014-12-04T11:02:37-05:00"
# File activesupport/lib/active_support/time_with_zone.rb, line 257 def yesterday? time.yesterday? end
Возвращает true, если текущее время объекта попадает в предыдущий день (вчера).
# File activesupport/lib/active_support/time_with_zone.rb, line 134 def zone period.abbreviation end
Возвращает аббревиатуру часового пояса.
Time.zone = 'Eastern Time (US & Canada)' # => "Eastern Time (US & Canada)" Time.zone.now.zone # => "EST"
© 2004–2020 David Heinemeier Hansson
Licensed under the MIT License.