класс ActiveSupport::TimeZone
Активное время зоны
Класс TimeZone служит оболочкой над экземплярами TZInfo::Timezone. Он позволяет нам сделать следующее:
-
Ограничить набор зон, предоставляемых TZInfo, до значимого подмножества 134 зон.
-
Получать и отображать зоны с более дружественным названием (например, «Восточное время (США и Канада)» вместо «America/New_York»).
-
Лениво загружать экземпляры
TZInfo::Timezoneтолько при необходимости. -
Создавать экземпляры
ActiveSupport::TimeWithZoneс помощью методов TimeZone:local,parse,at, иnow.
Если вы установите config.time_zone в приложении Rails, вы можете получить доступ к этому объекту TimeZone через Time.zone:
# application.rb: class Application < Rails::Application config.time_zone = 'Eastern Time (US & Canada)' end Time.zone # => #<ActiveSupport::TimeZone:0x514834...> Time.zone.name # => "Eastern Time (US & Canada)" Time.zone.now # => Sun, 18 May 2008 14:30:44 EDT -04:00
Константы
- MAPPING
-
Ключи — имена Rails
TimeZone, значения — идентификаторы TZInfo.
Атрибуты
Общедоступные методы класса
# File activesupport/lib/active_support/values/time_zone.rb, line 232
def [](arg)
case arg
when self
arg
when String
begin
@lazy_zones_map[arg] ||= create(arg)
rescue TZInfo::InvalidTimezoneIdentifier
nil
end
when TZInfo::Timezone
@lazy_zones_map[arg.name] ||= create(arg.name, nil, arg)
when Numeric, ActiveSupport::Duration
arg *= 3600 if arg.abs <= 13
all.find { |z| z.utc_offset == arg.to_i }
else
raise ArgumentError, "invalid argument to TimeZone[]: #{arg.inspect}"
end
end Поиск конкретного объекта часового пояса. Если аргумент — строка, она интерпретируется как имя часового пояса для поиска. Если это числовое значение, это либо смещение по часам, либо смещение по секундам часового пояса для поиска. (Будет возвращён первый с этим смещением). Возвращает nil , если такой часовой пояс системе не известен.
# File activesupport/lib/active_support/values/time_zone.rb, line 260 def country_zones(country_code) code = country_code.to_s.upcase @country_zones[code] ||= load_country_zones(code) end
Удобный метод для возвращения набора объектов TimeZone для часовых поясов в стране, указанной ее кодом ISO 3166-1 Alpha2.
# File activesupport/lib/active_support/values/time_zone.rb, line 300
Создаёт новый объект TimeZone с заданным именем и смещением. Смещение — это количество секунд, на которое этот часовой пояс смещён от UTC (GMT). В качестве единицы смещения выбраны секунды, потому что Руби использует секунды для представления смещений часовых поясов (см. Time#utc_offset).
# File activesupport/lib/active_support/values/time_zone.rb, line 207 def find_tzinfo(name) TZInfo::Timezone.get(MAPPING[name] || name) end
# File activesupport/lib/active_support/values/time_zone.rb, line 199 def seconds_to_utc_offset(seconds, colon = true) format = colon ? UTC_OFFSET_WITH_COLON : UTC_OFFSET_WITHOUT_COLON sign = (seconds < 0 ? "-" : "+") hours = seconds.abs / 3600 minutes = (seconds.abs % 3600) / 60 format % [sign, hours, minutes] end
Предполагает, что self представляет смещение от UTC в секундах (как возвращается Time#utc_offset) и преобразует его в строку формата +HH:MM.
ActiveSupport::TimeZone.seconds_to_utc_offset(-21_600) # => "-06:00"
# File activesupport/lib/active_support/values/time_zone.rb, line 254 def us_zones country_zones(:us) end
Удобный метод для возвращения набора объектов TimeZone для часовых поясов в США.
Общедоступные методы экземпляров
# File activesupport/lib/active_support/values/time_zone.rb, line 333 def <=>(zone) return unless zone.respond_to? :utc_offset result = (utc_offset <=> zone.utc_offset) result = (name <=> zone.name) if result == 0 result end
Сравнение часового пояса с параметром. Сначала сравниваются смещения, а затем имена.
# File activesupport/lib/active_support/values/time_zone.rb, line 342 def =~(re) re === name || re === MAPPING[name] end
Сравнение name и идентификатора TZInfo с предоставленным регулярным выражением, возвращая true в случае совпадения.
# File activesupport/lib/active_support/values/time_zone.rb, line 379 def at(*args) Time.at(*args).utc.in_time_zone(self) end
Метод для создания нового экземпляра ActiveSupport::TimeWithZone в часовом поясе self по количеству секунд, прошедших с эпохи Unix.
Time.zone = 'Hawaii' # => "Hawaii" Time.utc(2000).to_f # => 946684800.0 Time.zone.at(946684800.0) # => Fri, 31 Dec 1999 14:00:00 HST -10:00
Второй аргумент может быть использован для указания точности до долей секунды.
Time.zone = 'Hawaii' # => "Hawaii" Time.at(946684800, 123456.789).nsec # => 123456789
# File activesupport/lib/active_support/values/time_zone.rb, line 327 def formatted_offset(colon = true, alternate_utc_string = nil) utc_offset == 0 && alternate_utc_string || self.class.seconds_to_utc_offset(utc_offset, colon) end
Возвращает отформатированную строку смещения от UTC или альтернативную строку, если часовой пояс уже UTC.
zone = ActiveSupport::TimeZone['Central Time (US & Canada)'] zone.formatted_offset # => "-06:00" zone.formatted_offset(false) # => "-0600"
# File activesupport/lib/active_support/values/time_zone.rb, line 396
def iso8601(str)
# Historically `Date._iso8601(nil)` returns `{}`, but in the `date` gem versions `3.2.1`, `3.1.2`, `3.0.2`,
# and `2.0.1`, `Date._iso8601(nil)` raises `TypeError` https://github.com/ruby/date/issues/39
# Future `date` releases are expected to revert back to the original behavior.
raise ArgumentError, "invalid date" if str.nil?
parts = Date._iso8601(str)
year = parts.fetch(:year)
if parts.key?(:yday)
ordinal_date = Date.ordinal(year, parts.fetch(:yday))
month = ordinal_date.month
day = ordinal_date.day
else
month = parts.fetch(:mon)
day = parts.fetch(:mday)
end
time = Time.new(
year,
month,
day,
parts.fetch(:hour, 0),
parts.fetch(:min, 0),
parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0),
parts.fetch(:offset, 0)
)
if parts[:offset]
TimeWithZone.new(time.utc, self)
else
TimeWithZone.new(nil, self, time)
end
rescue Date::Error, KeyError
raise ArgumentError, "invalid date"
end Метод для создания нового экземпляра ActiveSupport::TimeWithZone в часовом поясе self из строки ISO 8601.
Time.zone = 'Hawaii' # => "Hawaii"
Time.zone.iso8601('1999-12-31T14:00:00') # => Fri, 31 Dec 1999 14:00:00 HST -10:00
Если компоненты времени отсутствуют, они будут установлены в ноль.
Time.zone = 'Hawaii' # => "Hawaii"
Time.zone.iso8601('1999-12-31') # => Fri, 31 Dec 1999 00:00:00 HST -10:00
Если строка некорректна, будет возбуждено исключение ArgumentError, в отличие от parse, которое обычно возвращает nil, при получении некорректной строки даты.
# File activesupport/lib/active_support/values/time_zone.rb, line 363 def local(*args) time = Time.utc(*args) ActiveSupport::TimeWithZone.new(nil, self, time) end
Метод для создания нового экземпляра ActiveSupport::TimeWithZone в часовом поясе self из заданных значений.
Time.zone = 'Hawaii' # => "Hawaii" Time.zone.local(2007, 2, 1, 15, 30, 45) # => Thu, 01 Feb 2007 15:30:45 HST -10:00
# File activesupport/lib/active_support/values/time_zone.rb, line 551 def local_to_utc(time, dst = true) tzinfo.local_to_utc(time, dst) end
Корректировка заданного времени до одновременного времени в UTC. Возвращает экземпляр Time.utc().
# File activesupport/lib/active_support/values/time_zone.rb, line 348
def match?(re)
(re == name) || (re == MAPPING[name]) ||
((Regexp === re) && (re.match?(name) || re.match?(MAPPING[name])))
end Сравнение name и идентификатора TZInfo с предоставленным регулярным выражением, возвращая true в случае совпадения.
# File activesupport/lib/active_support/values/time_zone.rb, line 516 def now time_now.utc.in_time_zone(self) end
Возвращает экземпляр ActiveSupport::TimeWithZone, представляющий текущее время в часовом поясе, представленном self.
Time.zone = 'Hawaii' # => "Hawaii" Time.zone.now # => Wed, 23 Jan 2008 20:24:27 HST -10:00
# File activesupport/lib/active_support/values/time_zone.rb, line 453 def parse(str, now = now()) parts_to_time(Date._parse(str, false), now) end
Метод для создания нового экземпляра ActiveSupport::TimeWithZone в часовом поясе self из проанализированной строки.
Time.zone = 'Hawaii' # => "Hawaii"
Time.zone.parse('1999-12-31 14:00:00') # => Fri, 31 Dec 1999 14:00:00 HST -10:00
Если верхние компоненты отсутствуют в строке, они берутся из TimeZone#now:
Time.zone.now # => Fri, 31 Dec 1999 14:00:00 HST -10:00
Time.zone.parse('22:30:00') # => Fri, 31 Dec 1999 22:30:00 HST -10:00
Однако, если компонент даты не задан, но заданы другие верхние компоненты, то день месяца по умолчанию равен 1:
Time.zone.parse('Mar 2000') # => Wed, 01 Mar 2000 00:00:00 HST -10:00
Если строка некорректна, может быть возбуждено исключение ArgumentError.
# File activesupport/lib/active_support/values/time_zone.rb, line 469
def rfc3339(str)
parts = Date._rfc3339(str)
raise ArgumentError, "invalid date" if parts.empty?
time = 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)
)
TimeWithZone.new(time.utc, self)
end Метод для создания нового экземпляра ActiveSupport::TimeWithZone в часовом поясе self из строки RFC 3339.
Time.zone = 'Hawaii' # => "Hawaii"
Time.zone.rfc3339('2000-01-01T00:00:00Z') # => Fri, 31 Dec 1999 14:00:00 HST -10:00
Если компоненты времени или часового пояса отсутствуют, будет возбуждено исключение ArgumentError. Это значительно строже, чем parse или iso8601, которые допускают отсутствие компонентов.
Time.zone = 'Hawaii' # => "Hawaii"
Time.zone.rfc3339('1999-12-31') # => ArgumentError: invalid date
# File activesupport/lib/active_support/values/time_zone.rb, line 507 def strptime(str, format, now = now()) parts_to_time(DateTime._strptime(str, format), now) end
Разбирает str в соответствии с format и возвращает ActiveSupport::TimeWithZone.
Предполагает, что str – это время в часовом поясе self, если в format не указан явный часовой пояс. (Это поведение аналогично parse). В любом случае, возвращаемый TimeWithZone имеет часовой пояс self.
Time.zone = 'Hawaii' # => "Hawaii"
Time.zone.strptime('1999-12-31 14:00:00', '%Y-%m-%d %H:%M:%S') # => Fri, 31 Dec 1999 14:00:00 HST -10:00
Если верхние компоненты отсутствуют в строке, они берутся из TimeZone#now:
Time.zone.now # => Fri, 31 Dec 1999 14:00:00 HST -10:00
Time.zone.strptime('22:30:00', '%H:%M:%S') # => Fri, 31 Dec 1999 22:30:00 HST -10:00
Однако, если компонент даты не задан, но заданы другие верхние компоненты, то день месяца по умолчанию равен 1:
Time.zone.strptime('Mar 2000', '%b %Y') # => Wed, 01 Mar 2000 00:00:00 HST -10:00
# File activesupport/lib/active_support/values/time_zone.rb, line 354
def to_s
"(GMT#{formatted_offset}) #{name}"
end Возвращает текстовое представление данного часового пояса.
# File activesupport/lib/active_support/values/time_zone.rb, line 521 def today tzinfo.now.to_date end
Возвращает текущую дату в данном часовом поясе.
# File activesupport/lib/active_support/values/time_zone.rb, line 526 def tomorrow today + 1 end
Возвращает следующую дату в данном часовом поясе.
# File activesupport/lib/active_support/values/time_zone.rb, line 317 def utc_offset @utc_offset || tzinfo&.current_period&.base_utc_offset end
Возвращает смещение данного часового пояса от UTC в секундах.
# File activesupport/lib/active_support/values/time_zone.rb, line 542
def utc_to_local(time)
tzinfo.utc_to_local(time).yield_self do |t|
ActiveSupport.utc_to_local_returns_utc_offset_times ?
t : Time.utc(t.year, t.month, t.day, t.hour, t.min, t.sec, t.sec_fraction * 1_000_000)
end
end Корректировка заданного времени до одновременного времени в часовом поясе, представленном self. Возвращает локальное время с соответствующим смещением — если вам нужен экземпляр ActiveSupport::TimeWithZone, используйте Time#in_time_zone() вместо этого.
Начиная с tzinfo 2, utc_to_local возвращает Time со смещением utc_offset, отличным от нуля. Подробнее см. в конфигурации utc_to_local_returns_utc_offset_times.
# File activesupport/lib/active_support/values/time_zone.rb, line 531 def yesterday today - 1 end
Возвращает предыдущую дату в данном часовом поясе.
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.