123456789_123456789_123456789_123456789_123456789_

Class: ActiveSupport::TimeZone

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Instance Chain:
self, Comparable
Inherits: Object
Defined in: activesupport/lib/active_support/values/time_zone.rb

Overview

=========================

The TimeZone class serves as a wrapper around TZInfo::Timezone instances. It allows us to do the following:

  • Limit the set of zones provided by TZInfo to a meaningful subset of 156 zones.
  • Retrieve and display zones with a friendlier name (e.g., "Eastern Time (US & Canada)" instead of "America/New_York").
  • Lazily load TZInfo::Timezone instances only when they're needed.
  • Create TimeWithZone instances via TimeZone's #local, #parse, #at, and #now methods.

If you set config.time_zone in the Rails Application, you can access this TimeZone object via 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

Constant Summary

  • MAPPING =

    Keys are Rails TimeZone names, values are TZInfo identifiers.

    # File 'activesupport/lib/active_support/values/time_zone.rb', line 38
    { # rubocop:disable Style/MutableConstant
      "International Date Line West" => "Etc/GMT+12",
      "Midway Island"                => "Pacific/Midway",
      "American Samoa"               => "Pacific/Pago_Pago",
      "Hawaii"                       => "Pacific/Honolulu",
      "Alaska"                       => "America/Juneau",
      "Pacific Time (US & Canada)"   => "America/Los_Angeles",
      "Pacific Time (Canada)"        => "America/Vancouver",
      "Tijuana"                      => "America/Tijuana",
      "Mountain Time (US & Canada)"  => "America/Denver",
      "Alberta"                      => "America/Edmonton",
      "Northwest Territories"        => "America/Inuvik",
      "Arizona"                      => "America/Phoenix",
      "Chihuahua"                    => "America/Chihuahua",
      "Mazatlan"                     => "America/Mazatlan",
      "Central Time (US & Canada)"   => "America/Chicago",
      "Manitoba"                     => "America/Winnipeg",
      "Saskatchewan"                 => "America/Regina",
      "Guadalajara"                  => "America/Mexico_City",
      "Mexico City"                  => "America/Mexico_City",
      "Monterrey"                    => "America/Monterrey",
      "Central America"              => "America/Guatemala",
      "Eastern Time (US & Canada)"   => "America/New_York",
      "Indiana (East)"               => "America/Indiana/Indianapolis",
      "Bogota"                       => "America/Bogota",
      "Lima"                         => "America/Lima",
      "Quito"                        => "America/Lima",
      "Atlantic Time (Canada)"       => "America/Halifax",
      "Caracas"                      => "America/Caracas",
      "La Paz"                       => "America/La_Paz",
      "Santiago"                     => "America/Santiago",
      "Asuncion"                     => "America/Asuncion",
      "Newfoundland"                 => "America/St_Johns",
      "Brasilia"                     => "America/Sao_Paulo",
      "Buenos Aires"                 => "America/Argentina/Buenos_Aires",
      "Montevideo"                   => "America/Montevideo",
      "Georgetown"                   => "America/Guyana",
      "Puerto Rico"                  => "America/Puerto_Rico",
      "Greenland"                    => "America/Nuuk",
      "Mid-Atlantic"                 => "Atlantic/South_Georgia",
      "Azores"                       => "Atlantic/Azores",
      "Cape Verde Is."               => "Atlantic/Cape_Verde",
      "Dublin"                       => "Europe/Dublin",
      "Edinburgh"                    => "Europe/London",
      "Lisbon"                       => "Europe/Lisbon",
      "London"                       => "Europe/London",
      "Casablanca"                   => "Africa/Casablanca",
      "Monrovia"                     => "Africa/Monrovia",
      "UTC"                          => "Etc/UTC",
      "Belgrade"                     => "Europe/Belgrade",
      "Bratislava"                   => "Europe/Bratislava",
      "Budapest"                     => "Europe/Budapest",
      "Ljubljana"                    => "Europe/Ljubljana",
      "Prague"                       => "Europe/Prague",
      "Sarajevo"                     => "Europe/Sarajevo",
      "Skopje"                       => "Europe/Skopje",
      "Warsaw"                       => "Europe/Warsaw",
      "Zagreb"                       => "Europe/Zagreb",
      "Brussels"                     => "Europe/Brussels",
      "Copenhagen"                   => "Europe/Copenhagen",
      "Madrid"                       => "Europe/Madrid",
      "Paris"                        => "Europe/Paris",
      "Amsterdam"                    => "Europe/Amsterdam",
      "Berlin"                       => "Europe/Berlin",
      "Bern"                         => "Europe/Zurich",
      "Zurich"                       => "Europe/Zurich",
      "Rome"                         => "Europe/Rome",
      "Stockholm"                    => "Europe/Stockholm",
      "Vienna"                       => "Europe/Vienna",
      "West Central Africa"          => "Africa/Algiers",
      "Bucharest"                    => "Europe/Bucharest",
      "Cairo"                        => "Africa/Cairo",
      "Helsinki"                     => "Europe/Helsinki",
      "Kyiv"                         => "Europe/Kyiv",
      "Riga"                         => "Europe/Riga",
      "Sofia"                        => "Europe/Sofia",
      "Tallinn"                      => "Europe/Tallinn",
      "Vilnius"                      => "Europe/Vilnius",
      "Athens"                       => "Europe/Athens",
      "Istanbul"                     => "Europe/Istanbul",
      "Minsk"                        => "Europe/Minsk",
      "Jerusalem"                    => "Asia/Jerusalem",
      "Harare"                       => "Africa/Harare",
      "Pretoria"                     => "Africa/Johannesburg",
      "Kaliningrad"                  => "Europe/Kaliningrad",
      "Moscow"                       => "Europe/Moscow",
      "St. Petersburg"               => "Europe/Moscow",
      "Volgograd"                    => "Europe/Volgograd",
      "Samara"                       => "Europe/Samara",
      "Kuwait"                       => "Asia/Kuwait",
      "Riyadh"                       => "Asia/Riyadh",
      "Nairobi"                      => "Africa/Nairobi",
      "Baghdad"                      => "Asia/Baghdad",
      "Tehran"                       => "Asia/Tehran",
      "Abu Dhabi"                    => "Asia/Muscat",
      "Muscat"                       => "Asia/Muscat",
      "Baku"                         => "Asia/Baku",
      "Tbilisi"                      => "Asia/Tbilisi",
      "Yerevan"                      => "Asia/Yerevan",
      "Kabul"                        => "Asia/Kabul",
      "Ekaterinburg"                 => "Asia/Yekaterinburg",
      "Islamabad"                    => "Asia/Karachi",
      "Karachi"                      => "Asia/Karachi",
      "Tashkent"                     => "Asia/Tashkent",
      "Chennai"                      => "Asia/Kolkata",
      "Kolkata"                      => "Asia/Kolkata",
      "Mumbai"                       => "Asia/Kolkata",
      "New Delhi"                    => "Asia/Kolkata",
      "Kathmandu"                    => "Asia/Kathmandu",
      "Dhaka"                        => "Asia/Dhaka",
      "Sri Jayawardenepura"          => "Asia/Colombo",
      "Almaty"                       => "Asia/Almaty",
      "Astana"                       => "Asia/Almaty",
      "Novosibirsk"                  => "Asia/Novosibirsk",
      "Rangoon"                      => "Asia/Yangon",
      "Bangkok"                      => "Asia/Bangkok",
      "Hanoi"                        => "Asia/Bangkok",
      "Jakarta"                      => "Asia/Jakarta",
      "Krasnoyarsk"                  => "Asia/Krasnoyarsk",
      "Beijing"                      => "Asia/Shanghai",
      "Chongqing"                    => "Asia/Chongqing",
      "Hong Kong"                    => "Asia/Hong_Kong",
      "Urumqi"                       => "Asia/Urumqi",
      "Kuala Lumpur"                 => "Asia/Kuala_Lumpur",
      "Singapore"                    => "Asia/Singapore",
      "Taipei"                       => "Asia/Taipei",
      "Perth"                        => "Australia/Perth",
      "Irkutsk"                      => "Asia/Irkutsk",
      "Ulaanbaatar"                  => "Asia/Ulaanbaatar",
      "Seoul"                        => "Asia/Seoul",
      "Osaka"                        => "Asia/Tokyo",
      "Sapporo"                      => "Asia/Tokyo",
      "Tokyo"                        => "Asia/Tokyo",
      "Yakutsk"                      => "Asia/Yakutsk",
      "Darwin"                       => "Australia/Darwin",
      "Adelaide"                     => "Australia/Adelaide",
      "Canberra"                     => "Australia/Canberra",
      "Melbourne"                    => "Australia/Melbourne",
      "Sydney"                       => "Australia/Sydney",
      "Brisbane"                     => "Australia/Brisbane",
      "Hobart"                       => "Australia/Hobart",
      "Vladivostok"                  => "Asia/Vladivostok",
      "Guam"                         => "Pacific/Guam",
      "Port Moresby"                 => "Pacific/Port_Moresby",
      "Magadan"                      => "Asia/Magadan",
      "Srednekolymsk"                => "Asia/Srednekolymsk",
      "Solomon Is."                  => "Pacific/Guadalcanal",
      "New Caledonia"                => "Pacific/Noumea",
      "Fiji"                         => "Pacific/Fiji",
      "Kamchatka"                    => "Asia/Kamchatka",
      "Marshall Is."                 => "Pacific/Majuro",
      "Auckland"                     => "Pacific/Auckland",
      "Wellington"                   => "Pacific/Auckland",
      "Nuku'alofa"                   => "Pacific/Tongatapu",
      "Tokelau Is."                  => "Pacific/Fakaofo",
      "Chatham Is."                  => "Pacific/Chatham",
      "Samoa"                        => "Pacific/Apia"
    }
  • TWO_DIGITS = private Internal use only
    # File 'activesupport/lib/active_support/values/time_zone.rb', line 197
    Array.new(60) { |n| format("%02d", n).freeze }.freeze
  • UTC_TIME = private
    # File 'activesupport/lib/active_support/values/time_zone.rb', line 667
    ::Time.utc(2000)

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(name) ⇒ TimeZone

Returns a TimeZone instance with the given name, or nil if no such TimeZone instance exists. (This exists to support the use of this class with the composed_of macro.)

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 228

def new(name)
  self[name]
end

#initialize(name, utc_offset = nil, tzinfo = nil) ⇒ TimeZone

This method is for internal use only.
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 333

def initialize(name, utc_offset = nil, tzinfo = nil)
  @name = name
  @utc_offset = utc_offset
  @tzinfo = tzinfo || TimeZone.find_tzinfo(name)
  @constant_period = constant_period(@tzinfo)
  @utc = constant_utc_zone?(@constant_period)

  ActiveSupport::Ractors.make_shareable(self)
end

Class Method Details

.[](arg)

Locate a specific time zone object. If the argument is a string, it is interpreted to mean the name of the timezone to locate. If it is a numeric value it is either the hour offset, or the second offset, of the timezone to find. (The first one with that offset will be returned.) Returns nil if no such time zone is known to the system.

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 244

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

.all

Returns an array of all TimeZone objects. There are multiple TimeZone objects per time zone, in many cases, to make it easier for users to find their own time zone.

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 235

def all
  @zones ||= zones_map.values.sort
end

.clear

This method is for internal use only.
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 277

def clear # :nodoc:
  @lazy_zones_map = Concurrent::Map.new
  @country_zones  = Concurrent::Map.new
  @zones = nil
  @zones_map = nil
end

.country_zones(country_code)

A convenience method for returning a collection of TimeZone objects for time zones in the country specified by its ISO 3166-1 Alpha2 code.

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 272

def country_zones(country_code)
  code = country_code.to_s.upcase
  @country_zones[code] ||= load_country_zones(code)
end

.create(name, utc_offset = nil, tzinfo = nil)

This method is for internal use only.

Create a new TimeZone object with the given name and offset. The offset is the number of seconds that this time zone is offset from UTC (GMT). Seconds were chosen as the offset unit because that is the unit that Ruby uses to represent time zone offsets (see Time#utc_offset).

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 223

RDoc directive :singleton-method: create

.find_tzinfo(name)

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 219

def find_tzinfo(name)
  TZInfo::Timezone.get(MAPPING[name] || name)
end

.load_country_zones(code) (private)

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 297

def load_country_zones(code)
  country = TZInfo::Country.get(code)
  country.zone_identifiers.flat_map do |tz_id|
    if MAPPING.value?(tz_id)
      MAPPING.inject([]) do |memo, (key, value)|
        memo << self[key] if value == tz_id
        memo
      end
    else
      create(tz_id, nil, TZInfo::Timezone.get(tz_id))
    end
  end.sort!
end

.make_shareable!

This method is for internal use only.
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 284

def make_shareable! # :nodoc:
  all
  TZInfo::Timezone.all_identifiers.each { |identifier| self[identifier] }
  TZInfo::Country.all_codes.each { |code| country_zones(code) }

  @lazy_zones_map = ActiveSupport::Ractors.make_shareable(@lazy_zones_map.each_pair.to_h)
  @country_zones  = ActiveSupport::Ractors.make_shareable(@country_zones.each_pair.to_h)
  ActiveSupport::Ractors.make_shareable(@zones)
  ActiveSupport::Ractors.make_shareable(@zones_map)
  ActiveSupport::Ractors.make_shareable(MAPPING)
end

.seconds_to_utc_offset(seconds, colon = true)

Assumes self represents an offset from UTC in seconds (as returned from Time#utc_offset) and turns this into an +HH:MM formatted string.

<code>seconds_to_utc_offset</code>(-21_600) # => "-06:00"
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 210

def seconds_to_utc_offset(seconds, colon = true)
  sign = seconds < 0 ? "-" : "+"
  hours = seconds.abs / 3600
  minutes = (seconds.abs % 3600) / 60
  hours = TWO_DIGITS[hours] || format("%02d", hours)
  minutes = TWO_DIGITS[minutes]
  colon ? "#{sign}#{hours}:#{minutes}" : "#{sign}#{hours}#{minutes}"
end

.us_zones

A convenience method for returning a collection of TimeZone objects for time zones in the USA.

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 266

def us_zones
  country_zones(:us)
end

.zones_map (private)

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 311

def zones_map
  @zones_map ||= MAPPING.each_with_object({}) do |(name, _), zones|
    timezone = self[name]
    zones[name] = timezone if timezone
  end
end

Instance Attribute Details

#name (readonly)

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 320

attr_reader :name

#tzinfo (readonly)

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 321

attr_reader :tzinfo

#utc? ⇒ Boolean (readonly)

This method is for internal use only.
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 355

def utc? # :nodoc:
  @utc
end

Instance Method Details

#<=>(zone)

Compare this time zone to the parameter. The two are compared first on their offsets, and then by name.

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 373

def <=>(zone)
  return unless zone.respond_to? :utc_offset
  result = (utc_offset <=> zone.utc_offset)
  result = (name <=> zone.name) if result == 0
  result
end

#=~(re)

Compare #name and TZInfo identifier to a supplied regexp, returning true if a match is found.

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 382

def =~(re)
  re === name || re === MAPPING[name]
end

#abbr(time)

This method is for internal use only.
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 649

def abbr(time) # :nodoc:
  tzinfo.abbr(time)
end

#at(*args)

Method for creating new TimeWithZone instance in time zone of self from number of seconds since the Unix epoch.

{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

A second argument can be supplied to specify sub-second precision.

{Time.zone} = 'Hawaii'                # => "Hawaii"
{Time.at}(946684800, 123456.789).nsec # => 123456789
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 425

def at(*args)
  Time.at(*args).utc.in_time_zone(self)
end

#constant_period(tzinfo) (private)

A zone without transitions, such as UTC, has a single period for all time. It is kept so that looking it up doesn't build a new one each time.

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 672

def constant_period(tzinfo)
  period = tzinfo.period_for_utc(UTC_TIME)
  period if period.start_transition.nil? && period.end_transition.nil?
end

#constant_utc_zone?(period) ⇒ Boolean (private)

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 677

def constant_utc_zone?(period)
  if period && period.observed_utc_offset == 0
    period.abbreviation == "UTC" || period.abbreviation == "UCT"
  end
end

#dst?(time) ⇒ Boolean

This method is for internal use only.
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 653

def dst?(time) # :nodoc:
  tzinfo.dst?(time)
end

#encode_with(coder)

This method is for internal use only.
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 661

def encode_with(coder) # :nodoc:
  coder.tag = "!ruby/object:#{self.class}"
  coder.map = { "name" => tzinfo.name }
end

#formatted_offset(colon = true, alternate_utc_string = nil)

Returns a formatted string of the offset from UTC, or an alternative string if the time zone is already UTC.

zone = ActiveSupport::TimeZone['Central Time (US & Canada)']
zone.formatted_offset        # => "-06:00"
zone.formatted_offset(false) # => "-0600"
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 367

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

#init_with(coder)

This method is for internal use only.
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 657

def init_with(coder) # :nodoc:
  initialize(coder["name"])
end

#iso8601(str)

Method for creating new TimeWithZone instance in time zone of self from an ISO 8601 string.

{Time.zone} = 'Hawaii'                     # => "Hawaii"
{Time.zone}.iso8601('1999-12-31T14:00:00') # => Fri, 31 Dec 1999 14:00:00 HST -10:00

If the time components are missing then they will be set to zero.

{Time.zone} = 'Hawaii'            # => "Hawaii"
{Time.zone}.iso8601('1999-12-31') # => Fri, 31 Dec 1999 00:00:00 HST -10:00

If the string is invalid then an ArgumentError will be raised unlike #parse which usually returns nil when given an invalid date string.

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 446

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.utc)
  end

rescue Date::Error, KeyError
  raise ArgumentError, "invalid date"
end

#local(*args)

Method for creating new TimeWithZone instance in time zone of self from given values.

{Time.zone} = 'Hawaii'                    # => "Hawaii"
{Time.zone}.local(2007, 2, 1, 15, 30, 45) # => Thu, 01 Feb 2007 15:30:45 HST -10:00
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 405

def local(*args)
  time = Time.utc(*args)
  ActiveSupport::TimeWithZone.new(nil, self, time)
end

#local_to_utc(time, dst = true)

Adjust the given time to the simultaneous time in UTC. Returns a Time.utc() instance.

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 633

def local_to_utc(time, dst = true)
  tzinfo.local_to_utc(time, dst)
end

#match?(re) ⇒ Boolean

Compare #name and TZInfo identifier to a supplied regexp, returning true if a match is found.

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 388

def match?(re)
  (re == name) || (re == MAPPING[name]) ||
    ((Regexp === re) && (re.match?(name) || re.match?(MAPPING[name])))
end

#now

Returns an TimeWithZone instance representing the current time in the time zone represented by self.

{Time.zone} = 'Hawaii'  # => "Hawaii"
{Time.zone}.now         # => Wed, 23 Jan 2008 20:24:27 HST -10:00
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 593

def now
  time_now.utc.in_time_zone(self)
end

#parse(str, now = now())

Method for creating new TimeWithZone instance in time zone of self from parsed string.

{Time.zone} = 'Hawaii'                   # => "Hawaii"
{Time.zone}.parse('1999-12-31 14:00:00') # => Fri, 31 Dec 1999 14:00:00 HST -10:00

If upper components are missing from the string, they are supplied from #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

However, if the date component is not provided, but any other upper components are supplied, then the day of the month defaults to 1:

{Time.zone}.parse('Mar 2000') # => Wed, 01 Mar 2000 00:00:00 HST -10:00

Strings with no recognizable date information return nil, while strings with out-of-range components raise ArgumentError:

{Time.zone}.parse('foobar') # => nil
{Time.zone}.parse('9000')   # => ArgumentError: argument out of range

Set ActiveSupport.raise_on_invalid_time_zone_parse to true to raise ArgumentError in both cases.

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 518

def parse(str, now = now())
  parts_to_time(Date._parse(str, false), now)
end

#parts_to_time(parts, now) (private)

Raises:

  • (ArgumentError)
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 683

def parts_to_time(parts, now)
  raise ArgumentError, "invalid date" if parts.nil?
  if parts.empty?
    raise ArgumentError, "invalid date" if ActiveSupport.raise_on_invalid_time_zone_parse
    return
  end

  if parts[:seconds]
    time = Time.at(parts[:seconds] + parts.fetch(:sec_fraction, 0))
  else
    time = Time.new(
      parts.fetch(:year) { now.year },
      parts.fetch(:mon) { now.month },
      parts.fetch(:mday) { parts[:year] || parts[:mon] ? 1 : now.day },
      parts.fetch(:hour, 0),
      parts.fetch(:min, 0),
      parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0),
      parts.fetch(:offset, 0)
    )
  end

  if parts[:offset] || parts[:seconds]
    TimeWithZone.new(time.utc, self)
  else
    TimeWithZone.new(nil, self, time.utc)
  end
end

#period_for_local(time, dst = true)

This method is for internal use only.
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 641

def period_for_local(time, dst = true) # :nodoc:
  @constant_period || tzinfo.period_for_local(time, dst) { |periods| periods.last }
end

#period_for_utc(time)

This method is for internal use only.
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 637

def period_for_utc(time) # :nodoc:
  @constant_period || tzinfo.period_for_utc(time)
end

#periods_for_local(time)

This method is for internal use only.
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 645

def periods_for_local(time) # :nodoc:
  tzinfo.periods_for_local(time)
end

#rfc3339(str)

Method for creating new TimeWithZone instance in time zone of self from an RFC 3339 string.

{Time.zone} = 'Hawaii'                     # => "Hawaii"
{Time.zone}.rfc3339('2000-01-01T00:00:00Z') # => Fri, 31 Dec 1999 14:00:00 HST -10:00

If the time or zone components are missing then an ArgumentError will be raised. This is much stricter than either #parse or #iso8601 which allow for missing components.

{Time.zone} = 'Hawaii'            # => "Hawaii"
{Time.zone}.rfc3339('1999-12-31') # => ArgumentError: invalid date

Raises:

  • (ArgumentError)
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 538

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

#standard_name

Returns a standard time zone name defined by IANA https://www.iana.org/time-zones

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 346

def standard_name
  MAPPING[name] || name
end

#strptime(str, format, now = now())

Parses str according to format and returns an TimeWithZone.

Assumes that str is a time in the time zone self, unless format includes an explicit time zone. (This is the same behavior as #parse.) In either case, the returned TimeWithZone has the timezone of 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

If upper components are missing from the string, they are supplied from #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

However, if the date component is not provided, but any other upper components are supplied, then the day of the month defaults to 1:

{Time.zone}.strptime('Mar 2000', '%b %Y') # => Wed, 01 Mar 2000 00:00:00 HST -10:00
[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 582

def strptime(str, format, now = now())
  parts_to_time(DateTime._strptime(str, format), now)
end

#time_now (private)

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 711

def time_now
  Time.now
end

#to_s

Returns a textual representation of this time zone.

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 394

def to_s
  "(GMT#{formatted_offset}) #{name}"
end

#today

Returns the current date in this time zone.

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 598

def today
  time = time_now.getutc
  if utc?
    time.to_date
  else
    time.getlocal(tzinfo.period_for(time).observed_utc_offset).to_date
  end
end

#tomorrow

Returns the next date in this time zone.

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 608

def tomorrow
  today + 1
end

#utc_offset

Returns the offset of this time zone from UTC in seconds.

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 351

def utc_offset
  @utc_offset || tzinfo&.current_period&.base_utc_offset
end

#utc_to_local(time)

Adjust the given time to the simultaneous time in the time zone represented by self. Returns a local time with the appropriate offset -- if you want an TimeWithZone instance, use Time#in_time_zone() instead.

As of tzinfo 2, utc_to_local returns a ::Time with a non-zero utc_offset. See the ActiveSupport#utc_to_local_returns_utc_offset_times config for more info.

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 624

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

#yesterday

Returns the previous date in this time zone.

[ GitHub ]

  
# File 'activesupport/lib/active_support/values/time_zone.rb', line 613

def yesterday
  today - 1
end