class Teasy::TimeWithZone

rubocop:disable Metrics/ClassLength

Constants

ZONE_ABBREV

matches valid format directives for zones

ZONE_COLONS_OFFSET
ZONE_COLON_OFFSET
ZONE_NO_COLON_OFFSET

Attributes

period[R]
time[R]

Public Class Methods

from_time(time, zone = Teasy.default_zone) click to toggle source

rubocop:enable Metrics/ParameterLists

# File lib/teasy/time_with_zone.rb, line 32
def self.from_time(time, zone = Teasy.default_zone)
  new(time.year, time.mon, time.day, time.hour, time.min, time.sec,
      time.nsec / 1_000.0, zone)
end
from_utc(utc_time, zone = Teasy.default_zone) click to toggle source
# File lib/teasy/time_with_zone.rb, line 37
def self.from_utc(utc_time, zone = Teasy.default_zone)
  from_time(utc_time, 'UTC').in_time_zone!(zone)
end
iso8601(string, zone = Teasy.default_zone) click to toggle source
# File lib/teasy/time_with_zone.rb, line 45
def self.iso8601(string, zone = Teasy.default_zone)
  from_utc(Time.iso8601(string).utc, zone)
end
new(year, month = nil, day = nil, hour = nil, minute = nil, second = nil, usec_with_frac = nil, zone = Teasy.default_zone) click to toggle source

rubocop:disable Metrics/ParameterLists

# File lib/teasy/time_with_zone.rb, line 23
def initialize(year, month = nil, day = nil,
               hour = nil, minute = nil, second = nil, usec_with_frac = nil,
               zone = Teasy.default_zone)
  @zone = tzinfo_time_zone(zone)
  @time = Time.utc(year, month, day, hour, minute, second, usec_with_frac)
  @period = determine_period(@time, @zone)
end
parse(string, zone = Teasy.default_zone) click to toggle source
# File lib/teasy/time_with_zone.rb, line 41
def self.parse(string, zone = Teasy.default_zone)
  from_utc(Time.parse(string).utc, zone)
end
strptime(string, format, zone = Teasy.default_zone) click to toggle source
# File lib/teasy/time_with_zone.rb, line 49
def self.strptime(string, format, zone = Teasy.default_zone)
  new(*DateTime._strptime(string, format).values, 'UTC').in_time_zone!(zone)
end

Public Instance Methods

+(other) click to toggle source
# File lib/teasy/time_with_zone.rb, line 112
def +(other)
  TimeWithZone.from_utc(utc_time + other, @zone.identifier)
end
-(other) click to toggle source
# File lib/teasy/time_with_zone.rb, line 116
def -(other)
  if other.is_a? Numeric
    TimeWithZone.from_utc(utc_time - other, @zone.identifier)
  elsif other.respond_to? :to_time
    to_time - other.to_time
  else
    raise TypeError, "#{other.class} can't be coerced into TimeWithZone"
  end
end
<=>(other) click to toggle source
# File lib/teasy/time_with_zone.rb, line 126
def <=>(other)
  return nil unless other.respond_to? :to_time

  to_time <=> other.to_time
end
asctime() click to toggle source
# File lib/teasy/time_with_zone.rb, line 106
def asctime
  strftime('%a %b %e %T %Y')
end
Also aliased as: ctime
ctime()
Alias for: asctime
eql?(other) click to toggle source
# File lib/teasy/time_with_zone.rb, line 132
def eql?(other)
  hash == other.hash
end
hash() click to toggle source
# File lib/teasy/time_with_zone.rb, line 136
def hash
  (utc.to_a << self.class).hash
end
in_time_zone(zone = Teasy.default_zone) click to toggle source
# File lib/teasy/time_with_zone.rb, line 62
def in_time_zone(zone = Teasy.default_zone)
  dup.in_time_zone!(zone)
end
in_time_zone!(zone = Teasy.default_zone) click to toggle source
# File lib/teasy/time_with_zone.rb, line 53
def in_time_zone!(zone = Teasy.default_zone)
  time = utc_time
  @zone = tzinfo_time_zone(zone)
  @time = @zone.utc_to_local(time)
  @period = @zone.period_for_utc(time)
  remove_instance_variable(:@local_time) if defined?(@local_time)
  self
end
inspect() click to toggle source
# File lib/teasy/time_with_zone.rb, line 94
def inspect
  format = utc? ? '%Y-%m-%d %H:%M:%S %Z' : '%Y-%m-%d %H:%M:%S %z'
  strftime(format)
end
Also aliased as: to_s
round(*args) click to toggle source
# File lib/teasy/time_with_zone.rb, line 90
def round(*args)
  dup.round!(*args)
end
round!(*args) click to toggle source
# File lib/teasy/time_with_zone.rb, line 85
def round!(*args)
  @time = @time.round(*args)
  self
end
strftime(format) click to toggle source
# File lib/teasy/time_with_zone.rb, line 101
def strftime(format)
  format = replace_zone_info(format) if includes_zone_directive?(format)
  time.strftime(format)
end
to_a() click to toggle source
# File lib/teasy/time_with_zone.rb, line 140
def to_a
  time.to_a[0..7] + [dst?, period.abbreviation.to_s]
end
to_s()
Alias for: inspect
to_time() click to toggle source
# File lib/teasy/time_with_zone.rb, line 144
def to_time
  return @local_time if defined?(@local_time)

  params = %i[year mon day hour min].map! { |m| @time.send(m) }
  params << @time.sec + @time.subsec
  @local_time = utc? ? Time.utc(*params) : Time.new(*params, utc_offset)
end
utc() click to toggle source
# File lib/teasy/time_with_zone.rb, line 81
def utc
  dup.utc!
end
utc!() click to toggle source
# File lib/teasy/time_with_zone.rb, line 74
def utc!
  @time = @zone.local_to_utc(@time, @period.dst?)
  @zone = tzinfo_time_zone('UTC')
  @period = @zone.period_for_local(@time)
  self
end
utc?() click to toggle source
# File lib/teasy/time_with_zone.rb, line 70
def utc?
  @zone.identifier == 'UTC'
end
zone() click to toggle source
# File lib/teasy/time_with_zone.rb, line 66
def zone
  @zone.identifier
end

Private Instance Methods

determine_period(time, zone = Teasy.default_zone) click to toggle source
# File lib/teasy/time_with_zone.rb, line 154
def determine_period(time, zone = Teasy.default_zone)
  zone.period_for_local(time) do |results|
    Teasy.ambiguous_time_handler.call(time, results)
  end
rescue TZInfo::PeriodNotFound
  period, time = Teasy.period_not_found_handler.call(time, zone)
  @time = time
  period
end
formatted_offset(offset_in_seconds, colon = false, seconds = false) click to toggle source

rubocop:disable Style/OptionalBooleanParameter

# File lib/teasy/time_with_zone.rb, line 200
def formatted_offset(offset_in_seconds, colon = false, seconds = false)
  sign = offset_in_seconds.negative? ? '-' : '+'
  hours = offset_in_seconds.abs / 3600
  minutes = (offset_in_seconds.abs % 3600) / 60

  separator = colon ? ':' : ''
  string_format = ['%s%02d', '%02d', ('%02d' if seconds)]
                  .compact.join(separator)
  args = [sign, hours, minutes, ((offset_in_seconds.abs % 60) if seconds)]
         .compact

  format(string_format, *args)
end
includes_zone_directive?(format) click to toggle source
# File lib/teasy/time_with_zone.rb, line 182
def includes_zone_directive?(format)
  zone_directives_matcher =~ format
end
replace_zone_info(format) click to toggle source
# File lib/teasy/time_with_zone.rb, line 186
def replace_zone_info(format)
  format_with_zone = format.gsub(ZONE_ABBREV, period.abbreviation.to_s)
  format_with_zone.gsub!(ZONE_NO_COLON_OFFSET, formatted_offset(utc_offset))
  format_with_zone.gsub!(
    ZONE_COLON_OFFSET, formatted_offset(utc_offset, :with_colon)
  )
  format_with_zone.gsub!(
    ZONE_COLONS_OFFSET,
    formatted_offset(utc_offset, :with_colon, :with_seconds)
  )
  format_with_zone
end
tzinfo_time_zone(time_zone) click to toggle source

rubocop:enable Style/OptionalBooleanParameter

# File lib/teasy/time_with_zone.rb, line 215
def tzinfo_time_zone(time_zone)
  Teasy.with_zone(time_zone) { |zone| TZInfo::Timezone.get(zone) }
end
utc_time() click to toggle source
# File lib/teasy/time_with_zone.rb, line 164
def utc_time
  @utc_time ||= @zone.local_to_utc(@time)
end
zone_directives_matcher() click to toggle source
# File lib/teasy/time_with_zone.rb, line 176
def zone_directives_matcher
  @zone_directives_matcher ||= Regexp.union(
    ZONE_ABBREV, ZONE_NO_COLON_OFFSET, ZONE_COLON_OFFSET, ZONE_COLONS_OFFSET
  )
end