Module: Lazier::TimeZone

Extended by:
ActiveSupport::Concern
Defined in:
lib/lazier/timezone.rb

Overview

Extensions for TimeZone objects.

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

ALREADY_PARAMETERIZED =

Pattern for a parameterized timezone.

/^[+-]\d{4}@[a-z-]+/
PARAMETERIZER =

Pattern for a unparameterized timezone.

/^(
  \(
    [a-z]+ # UTC Label
    (?<offset>([+-])(\d{2})(:?)(\d{2}))
  \)
  \s(?<label>.+)
)$/xi

Instance Method Summary collapse

Instance Method Details

#aliasesArray

Returns a list of valid aliases (city names) for this timezone (basing on the offset).

Returns:

  • (Array)

    A list of aliases for this timezone



154
155
156
157
# 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_aliasString

Returns the current alias for this timezone.

Returns:

  • (String)

    The current alias or the first alias of the current timezone.



172
173
174
175
176
177
178
179
# 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) ⇒ Object

Sets the current alias.

Parameters:

  • new_alias (String)

    The new current alias.



184
185
186
# 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) ⇒ String

Returns the current name.

Parameters:

  • dst (Boolean) (defaults to: false)

    Whether to return the name with DST indication.

  • dst_label (String) (defaults to: " (DST)")

    Label for the DST indication. Defaults to (DST).

  • year (Fixnum) (defaults to: nil)

    The year to which refer to. Defaults to the current year. Only required when dst is true.

Returns:

  • (String)

    The name for the zone.



194
195
196
197
198
199
# 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) ⇒ Fixnum|Rational

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

Parameters:

  • rational (Boolean) (defaults to: false)

    Whether to return the offset as a Rational.

  • date (DateTime|NilClass) (defaults to: nil)

    The date to consider. Defaults to now.

Returns:

  • (Fixnum|Rational)

    The offset of this timezone.



164
165
166
167
# 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) ⇒ Fixnum|Rational

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

Parameters:

  • rational (Boolean) (defaults to: false)

    Whether to return the offset as a Rational.

  • year (Fixnum|NilClass) (defaults to: nil)

    The year to which refer to. Defaults to the current year.

Returns:

  • (Fixnum|Rational)

    The correction for dst.



250
251
252
253
# 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) ⇒ TimezonePeriod

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

Parameters:

  • year (Fixnum|NilClass) (defaults to: nil)

    The year to which refer to. Defaults to the current year.

Returns:

  • (TimezonePeriod)

    A period when the Daylight Saving Time (DST) is active or nil if the timezone doesn't use DST for that year.



235
236
237
238
239
240
241
242
243
# 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) ⇒ Fixnum|Rational

Returns the standard offset for this timezone.

Parameters:

  • rational (Boolean) (defaults to: false)

    Whether to return he offset as a Rational.

  • dst (Boolean) (defaults to: false)

    Whether to return the offset when the DST is active.

  • year (Fixnum|NilClass) (defaults to: nil)

    The year to which refer to. Defaults to the current year.

Returns:

  • (Fixnum|Rational)

    The offset of this timezone.



207
208
209
210
211
212
213
214
215
216
217
# 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) ⇒ String

Formats this zone as a string.

Parameters:

  • dst (Boolean) (defaults to: false)

    Whether to represent with (DST) active.

  • args (Hash)

    Parameters for the formatting:

Options Hash (**args):

  • label (String)

    : The label to use. Default to the current alias.

  • dst_label (String)

    : Label for the DST indication. Defaults to (DST).

  • utc_label (String)

    : Label for the UTC name. Defaults to GMT. *Only used when parameterized is false.

  • year (Fixnum)

    : The year to which refer to. Defaults to the current year.

  • parameterized (Boolean)

    : Whether to represent as parameterized.

  • with_offset (Boolean)

    : Whether to include offset into the representation. *Only used when parameterized is true.

  • offset_position (Symbol)

    : Where to put the offset. Valid values are :begin or :end. *Only used when parameterized is false.

  • colon (Boolean)

    : If include a colon in the offset. *Only used when parameterized is false.

Returns:

  • (String)

    The string representation for this zone.



268
269
270
271
272
273
274
275
276
277
278
# 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) ⇒ Boolean

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

Parameters:

  • reference (Date|DateTime|NilClass) (defaults to: nil)

    The date or year to check. Defaults to the current year.

Returns:

  • (Boolean)

    true if the zone uses DST for that date or year, false otherwise.



223
224
225
226
227
228
229
# 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