module Lazier::TimeZone

Extensions for `TimeZone` objects.

Constants

ALREADY_PARAMETERIZED

Pattern for a parameterized timezone.

PARAMETERIZER

Pattern for a unparameterized timezone.

Public Instance Methods

aliases() click to toggle source

Returns a list of valid aliases (city names) for this timezone (basing on the offset). @return [Array] A list of aliases for this timezone

# File lib/lazier/timezone.rb, line 154
def aliases
  reference = self.class::MAPPING.fetch(name, name).gsub("_", " ")
  @aliases ||= ([reference] + self.class::MAPPING.map { |name, zone| format_alias(name, zone, reference) }).uniq.compact.sort
end
current_alias() click to toggle source

Returns the current alias for this timezone.

@return [String] The current alias or the first alias of the current timezone.

# File lib/lazier/timezone.rb, line 172
def current_alias
  if @current_alias
    @current_alias
  else
    identifier = name
    aliases.find { |a| a == identifier } || aliases.first
  end
end
current_alias=(new_alias) click to toggle source

Sets the current alias.

@param new_alias [String] The new current alias.

# File lib/lazier/timezone.rb, line 184
def current_alias=(new_alias)
  @current_alias = new_alias.ensure_string
end
current_name(dst = false, dst_label: " (DST)", year: nil) click to toggle source

Returns the current name.

@param dst [Boolean] Whether to return the name with DST indication. @param dst_label [String] Label for the DST indication. Defaults to ` (DST)`. @param year [Fixnum] The year to which refer to. Defaults to the current year. *Only required when `dst` is true*. @return [String] The name for the zone.

# File lib/lazier/timezone.rb, line 194
def current_name(dst = false, dst_label: " (DST)", year: nil)
  year ||= Date.current.year
  rv = current_alias
  rv += dst_label if dst && uses_dst?(year)
  rv
end
current_offset(rational = false, date = nil) click to toggle source

Returns the current offset for this timezone, taking care of Daylight Saving Time (DST).

@param rational [Boolean] Whether to return the offset as a Rational. @param date [DateTime|NilClass] The date to consider. Defaults to now. @return [Fixnum|Rational] The offset of this timezone.

# File lib/lazier/timezone.rb, line 164
def current_offset(rational = false, date = nil)
  date = (date || ::DateTime.current).in_time_zone
  offset(rational: rational, dst: date.dst?, year: date.year)
end
dst_correction(rational = false, year = nil) click to toggle source

Return the correction applied to the standard offset the timezone when the Daylight Saving Time (DST) is active.

@param rational [Boolean] Whether to return the offset as a Rational. @param year [Fixnum|NilClass] The year to which refer to. Defaults to the current year. @return [Fixnum|Rational] The correction for dst.

# File lib/lazier/timezone.rb, line 250
def dst_correction(rational = false, year = nil)
  rv = dst_offset(year, :std_offset)
  rational ? self.class.rationalize_offset(rv) : rv
end
dst_period(year = nil) click to toggle source

Gets a period for this timezone when the Daylight Saving Time (DST) is active (it takes care of different hemispheres).

@param year [Fixnum|NilClass] The year to which refer to. Defaults to the current year. @return [TimezonePeriod] A period when the Daylight Saving Time (DST) is active or `nil` if the timezone doesn't use DST for that year.

# File lib/lazier/timezone.rb, line 235
def dst_period(year = nil)
  year ||= ::Date.current.year

  period = period_for_utc(::DateTime.civil(year, 7, 15, 12).utc) # Summer for the northern hemisphere
  period = period_for_utc(::DateTime.civil(year, 1, 15, 12).utc) unless period.dst? # Summer for the southern hemisphere
  period.dst? ? period : nil
rescue
  nil
end
offset(rational: false, dst: false, year: nil) click to toggle source

Returns the standard offset for this timezone.

@param rational [Boolean] Whether to return he offset as a `Rational`. @param dst [Boolean] Whether to return the offset when the DST is active. @param year [Fixnum|NilClass] The year to which refer to. Defaults to the current year. @return [Fixnum|Rational] The offset of this timezone.

# File lib/lazier/timezone.rb, line 207
def offset(rational: false, dst: false, year: nil)
  rv =
    if dst
      period = dst_period(year)
      period ? period.utc_total_offset : 0
    else
      utc_offset
    end

  rational ? self.class.rationalize_offset(rv) : rv
end
to_str(dst = false, **args) click to toggle source

Formats this zone as a string.

@param dst [Boolean] Whether to represent with (DST) active. @param args [Hash] Parameters for the formatting: @option args label [String]: The label to use. Default to the current alias. @option args dst_label [String]: Label for the DST indication. Defaults to ` (DST)`. @option args utc_label [String]: Label for the UTC name. Defaults to `GMT`. *Only used when `parameterized` is `false`. @option args year [Fixnum]: The year to which refer to. Defaults to the current year. @option args parameterized [Boolean]: Whether to represent as parameterized. @option args with_offset [Boolean]: Whether to include offset into the representation. *Only used when `parameterized` is `true`. @option args offset_position [Symbol]: Where to put the offset. Valid values are `:begin` or `:end`. *Only used when `parameterized` is `false`. @option args colon [Boolean]: If include a colon in the offset. *Only used when `parameterized` is `false`. @return [String] The string representation for this zone.

# File lib/lazier/timezone.rb, line 268
def to_str(dst = false, **args)
  # PI: Ignore reek on this.
  label, dst_label, utc_label, year, parameterized, with_offset, colon, offset_position = prepare_to_str_arguments(args)

  if parameterized
    self.class.parameterize(to_str(dst, label: label, dst_label: dst_label, utc_label: utc_label, year: year, parameterized: false), with_offset)
  else
    offset_label = self.class.seconds_to_utc_offset(offset(rational: false, dst: dst, year: year), colon)
    to_str_unparameterized(dst ? dst_label : "", label, offset_label, offset_position, utc_label, with_offset)
  end
end
uses_dst?(reference = nil) click to toggle source

Checks if the timezone uses Daylight Saving Time (DST) for that date or year.

@param reference [Date|DateTime|NilClass] The date or year to check. Defaults to the current year. @return [Boolean] `true` if the zone uses DST for that date or year, `false` otherwise.

# File lib/lazier/timezone.rb, line 223
def uses_dst?(reference = nil)
  if reference.is_a?(Date) || reference.is_a?(DateTime) || reference.is_a?(Time)
    period_for_utc(reference).dst?
  else
    dst_period(reference)
  end
end

Private Instance Methods

format_alias(name, zone, reference) click to toggle source

:nodoc

# File lib/lazier/timezone.rb, line 283
def format_alias(name, zone, reference)
  if zone.gsub("_", " ") == reference
    ["International Date Line West", "UTC"].include?(name) || name.include?("(US & Canada)") ? name : reference.gsub(/\/.*/, "/#{name}")
  end
end