class EtOrbi::EoTime

Our EoTime class (which quacks like a ::Time).

An EoTime instance should respond to most of the methods ::Time instances respond to. If a method is missing, feel free to open an issue to ask (politely) for it. If it makes sense, it'll get added, else a workaround will get suggested. The immediate workaround is to call to_t on the EoTime instance to get equivalent ::Time instance in the local, current, timezone.

Constants

WEEK_S

Attributes

seconds[R]

instance methods

zone[R]

Public Class Methods

get_tzone(o) click to toggle source
# File lib/et-orbi.rb, line 267
def get_tzone(o)

  EtOrbi.get_tzone(o)
end
local(*a) click to toggle source
# File lib/et-orbi.rb, line 292
def local(*a)

  EtOrbi.make_from_array(a, local_tzone)
end
local_tzone() click to toggle source
# File lib/et-orbi.rb, line 272
def local_tzone

  EtOrbi.determine_local_tzone
end
make(o) click to toggle source
# File lib/et-orbi.rb, line 282
def make(o)

  EtOrbi.make_time(o)
end
new(s, zone) click to toggle source
# File lib/et-orbi.rb, line 304
def initialize(s, zone)

  @seconds = s.to_f
  @zone = self.class.get_tzone(zone || :local)

  fail ArgumentError.new(
    "Cannot determine timezone from #{zone.inspect}" +
    "\n#{EtOrbi.render_nozone_time(@seconds)}" +
    "\n#{EtOrbi.platform_info.sub(',debian:', ",\ndebian:")}" +
    "\nTry setting `ENV['TZ'] = 'Continent/City'` in your script " +
    "(see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)" +
    (defined?(TZInfo::Data) ? '' : "\nand adding gem 'tzinfo-data'")
  ) unless @zone

  @time = nil
    # cache for #to_time result
end
now(zone=nil) click to toggle source
# File lib/et-orbi.rb, line 257
def now(zone=nil)

  EtOrbi.now(zone)
end
parse(str, opts={}) click to toggle source
# File lib/et-orbi.rb, line 262
def parse(str, opts={})

  EtOrbi.parse(str, opts)
end
platform_info() click to toggle source
# File lib/et-orbi.rb, line 277
def platform_info

  EtOrbi.platform_info
end
utc(*a) click to toggle source
# File lib/et-orbi.rb, line 287
def utc(*a)

  EtOrbi.make_from_array(a, EtOrbi.get_tzone('UTC'))
end

Public Instance Methods

+(t) click to toggle source
# File lib/et-orbi.rb, line 450
def +(t); inc(t, 1); end
-(t) click to toggle source
# File lib/et-orbi.rb, line 451
def -(t); inc(t, -1); end
<(o) click to toggle source
# File lib/et-orbi.rb, line 443
def <(o); @seconds < _to_f(o); end
<=(o) click to toggle source
# File lib/et-orbi.rb, line 444
def <=(o); @seconds <= _to_f(o); end
<=>(o) click to toggle source
# File lib/et-orbi.rb, line 445
def <=>(o); @seconds <=> _to_f(o); end
==(o) click to toggle source
# File lib/et-orbi.rb, line 433
def ==(o)

  o.is_a?(EoTime) &&
  o.seconds == @seconds &&
  (o.zone == @zone || o.zone.current_period == @zone.current_period)
end
>(o) click to toggle source

alias eql? == # FIXME see Object#== (ri)

# File lib/et-orbi.rb, line 441
def >(o); @seconds > _to_f(o); end
>=(o) click to toggle source
# File lib/et-orbi.rb, line 442
def >=(o); @seconds >= _to_f(o); end
add(t) click to toggle source
# File lib/et-orbi.rb, line 447
def add(t); @time = nil; @seconds += t.to_f; self; end
ambiguous?() click to toggle source

Returns true if this EoTime instance corresponds to 2 different UTC times. It happens when transitioning from DST to winter time.

www.timeanddate.com/time/change/usa/new-york?year=2018

# File lib/et-orbi.rb, line 340
def ambiguous?

  @zone.local_to_utc(@zone.utc_to_local(utc))

  false

rescue TZInfo::AmbiguousTime

  true
end
getgm()
Alias for: utc
getutc()
Alias for: utc
inc(t, dir=1) click to toggle source
# File lib/et-orbi.rb, line 515
def inc(t, dir=1)

  case t
  when Numeric
    nt = self.dup
    nt.seconds += dir * t.to_f
    nt
  when ::Time, ::EtOrbi::EoTime
    fail ArgumentError.new(
      "Cannot add #{t.class} to EoTime") if dir > 0
    @seconds + dir * t.to_f
  else
    fail ArgumentError.new(
      "Cannot call add or subtract #{t.class} to EoTime instance")
  end
end
is_dst?() click to toggle source
# File lib/et-orbi.rb, line 401
def is_dst?

  @zone.period_for_utc(utc).std_offset != 0
end
Also aliased as: isdst
isdst()
Alias for: is_dst?
iso8601(fraction_digits=0) click to toggle source
# File lib/et-orbi.rb, line 490
def iso8601(fraction_digits=0)

  s = (fraction_digits || 0) > 0 ? ".%#{fraction_digits}N" : ''
  strftime("%Y-%m-%dT%H:%M:%S#{s}%:z")
end
localtime(zone=nil) click to toggle source
# File lib/et-orbi.rb, line 532
def localtime(zone=nil)

  EoTime.new(self.to_f, zone)
end
Also aliased as: translate
monthdays() click to toggle source
# File lib/et-orbi.rb, line 455
def monthdays

  date = to_time

  pos = 1
  d = self.dup

  loop do
    d.add(-WEEK_S)
    break if d.month != date.month
    pos = pos + 1
  end

  neg = -1
  d = self.dup

  loop do
    d.add(WEEK_S)
    break if d.month != date.month
    neg = neg - 1
  end

  [ "#{date.wday}##{pos}", "#{date.wday}##{neg}" ]
end
reach(points) click to toggle source
# File lib/et-orbi.rb, line 544
def reach(points)

  t = EoTime.new(self.to_f, @zone)
  step = 1

  s = points[:second] || points[:sec] || points[:s]
  m = points[:minute] || points[:min] || points[:m]
  h = points[:hour] || points[:hou] || points[:h]

  fail ArgumentError.new("missing :second, :minute, and :hour")          unless s || m || h

  if !s && !m
    step = 60 * 60
    t -= t.sec
    t -= t.min * 60
  elsif !s
    step = 60
    t -= t.sec
  end

  loop do
    t += step
    next if s && t.sec != s
    next if m && t.min != m
    next if h && t.hour != h
    break
  end

  t
end
seconds=(f) click to toggle source
# File lib/et-orbi.rb, line 322
def seconds=(f)

  @time = nil
  @seconds = f
end
strftime(format) click to toggle source
# File lib/et-orbi.rb, line 382
def strftime(format)

  format = format.gsub(/%(\/?Z|:{0,2}z)/) { |f| strfz(f) }

  to_time.strftime(format)
end
subtract(t) click to toggle source
# File lib/et-orbi.rb, line 448
def subtract(t); @time = nil; @seconds -= t.to_f; self; end
to_debug_s() click to toggle source
# File lib/et-orbi.rb, line 407
def to_debug_s

  uo = self.utc_offset
  uos = uo < 0 ? '-' : '+'
  uo = uo.abs
  uoh, uom = [ uo / 3600, uo % 3600 ]

  [
    'ot',
    self.strftime('%Y-%m-%d %H:%M:%S'),
    "%s%02d:%02d" % [ uos, uoh, uom ],
    "dst:#{self.isdst}"
  ].join(' ')
end
to_f() click to toggle source
# File lib/et-orbi.rb, line 372
def to_f

  @seconds
end
to_i() click to toggle source
# File lib/et-orbi.rb, line 377
def to_i

  @seconds.to_i
end
to_local_time() click to toggle source

Returns this ::EtOrbi::EoTime as a ::Time instance in the current timezone.

Has a to_t alias.

# File lib/et-orbi.rb, line 394
def to_local_time

  Time.at(@seconds)
end
Also aliased as: to_t
to_s() click to toggle source
# File lib/et-orbi.rb, line 480
def to_s

  strftime('%Y-%m-%d %H:%M:%S %z')
end
to_t()
Alias for: to_local_time
to_time_s() click to toggle source
# File lib/et-orbi.rb, line 510
def to_time_s

  strftime("%H:%M:%S.#{'%06d' % usec}")
end
to_utc_comparison_s() click to toggle source

Debug current time by showing local time / delta / utc time for example: “0120-7(0820)”

# File lib/et-orbi.rb, line 499
def to_utc_comparison_s

  per = @zone.period_for_utc(utc)
  off = per.utc_total_offset

  off = off / 3600
  off = off >= 0 ? "+#{off}" : off.to_s

  strftime('%H%M') + off + utc.strftime('(%H%M)')
end
to_utc_time()
Alias for: utc
to_zs() click to toggle source
# File lib/et-orbi.rb, line 485
def to_zs

  strftime('%Y-%m-%d %H:%M:%S %/Z')
end
translate(zone=nil)
Alias for: localtime
utc() click to toggle source

Returns this ::EtOrbi::EoTime as a ::Time instance in the current UTC timezone.

# File lib/et-orbi.rb, line 354
def utc

  Time.utc(1970) + @seconds
end
Also aliased as: getutc, getgm, to_utc_time
utc?() click to toggle source

Returns true if this ::EtOrbi::EoTime instance timezone is UTC. Returns false else.

# File lib/et-orbi.rb, line 362
def utc?

  %w[ gmt utc zulu etc/gmt etc/utc ].include?(
    @zone.canonical_identifier.downcase)
end
utc_offset() click to toggle source
# File lib/et-orbi.rb, line 422
def utc_offset

  @zone.period_for_utc(utc).utc_offset
end
wday_in_month() click to toggle source
# File lib/et-orbi.rb, line 539
def wday_in_month

  [ count_weeks(-1), - count_weeks(1) ]
end
zone=(z) click to toggle source
# File lib/et-orbi.rb, line 328
def zone=(z)

  @time = nil
  @zone = self.class.get_tzone(zone || :current)
end

Protected Instance Methods

_to_f(o) click to toggle source
# File lib/et-orbi.rb, line 626
def _to_f(o)

  fail ArgumentError(
    "Comparison of EoTime with #{o.inspect} failed"
  ) unless o.is_a?(EoTime) || o.is_a?(Time)

  o.to_f
end
count_weeks(dir) click to toggle source
# File lib/et-orbi.rb, line 588
def count_weeks(dir)

  c = 0
  t = self
  until t.month != self.month
    c += 1
    t += dir * (7 * 24 * 3600)
  end

  c
end
strfz(code) click to toggle source
# File lib/et-orbi.rb, line 600
def strfz(code)

  return @zone.name if code == '%/Z'

  per = @zone.period_for_utc(utc)

  return per.abbreviation.to_s if code == '%Z'

  off = per.utc_total_offset
    #
  sn = off < 0 ? '-' : '+'; off = off.abs
  hr = off / 3600
  mn = (off % 3600) / 60
  sc = 0

  if @zone.name == 'UTC'
    'Z' # align on Ruby ::Time#iso8601
  elsif code == '%z'
    '%s%02d%02d' % [ sn, hr, mn ]
  elsif code == '%:z'
    '%s%02d:%02d' % [ sn, hr, mn ]
  else
    '%s%02d:%02d:%02d' % [ sn, hr, mn, sc ]
  end
end
to_time() click to toggle source

Returns a Ruby Time instance.

Warning: the timezone of that Time instance will be UTC when used with TZInfo < 2.0.0.

# File lib/et-orbi.rb, line 583
def to_time

  @time ||= @zone.utc_to_local(utc)
end