lib/et-orbi.rb in et-orbi-1.0.5 vs lib/et-orbi.rb in et-orbi-1.0.6

- old
+ new

@@ -5,11 +5,11 @@ require 'tzinfo' module EtOrbi - VERSION = '1.0.5' + VERSION = '1.0.6' # # module methods class << self @@ -34,43 +34,52 @@ end #if rold # # is necessary since Time.parse('xxx') in Ruby < 1.9 yields `now` str_zone = get_tzone(list_iso8601_zones(str).last) +#p [ :parse, str, str_zone ] +#p ENV['TZ'] +#p [ :parse, :oz, opts[:zone] ] +#p [ :parse, :sz, str_zone ] +#p [ :parse, :foz, find_olson_zone(str) ] +#p [ :parse, :ltz, local_tzone ] zone = opts[:zone] || str_zone || find_olson_zone(str) || local_tzone +#p [ :parse, :zone, zone ] str = str.sub(zone.name, '') unless zone.name.match(/\A[-+]/) # # for 'Sun Nov 18 16:01:00 Asia/Singapore 2012', # although where does rufus-scheduler have it from? local = Time.parse(str) +#p [ :parse, :local, local, local.zone ] secs = if str_zone local.to_f else zone.period_for_local(local).to_utc(local).to_f end +#p [ :parse, :secs, secs ] EoTime.new(secs, zone) end def make_time(*a) -#p a +#p [ :mt, a ] zone = a.length > 1 ? get_tzone(a.last) : nil a.pop if zone #p [ :mt, zone ] o = a.length > 1 ? a : a.first -#p o +#p [ :mt, :o, o ] case o when Time then make_from_time(o, zone) when Date then make_from_date(o, zone) when Array then make_from_array(o, zone) @@ -85,16 +94,16 @@ def make_from_time(t, zone) z = zone || get_tzone(t.zone) || - ( - local_tzone.period_for_local(t).abbreviation.to_s == t.zone && - local_tzone - ) || - t.zone + get_local_tzone(t) + z ||= t.zone + # pass the abbreviation anyway, + # it will be used in resulting the error message + EoTime.new(t.to_f, z) end def make_from_date(d, zone) @@ -113,10 +122,11 @@ make_from_string(s, zone) end def make_from_string(s, zone) +#p [ :mfs, s, zone ] parse(s, zone: zone) end def make_from_numeric(f, zone) @@ -158,10 +168,25 @@ @local_tzone_loaded_at = Time.now determine_local_tzone end end + def render_nozone_time(seconds) + + t = + Time.utc(0) + seconds + ts = + t.strftime('%Y-%m-%d %H:%M:%S') + + ".#{(seconds % 1).to_s.split('.').last}" + z = + EtOrbi.local_tzone ? + EtOrbi.local_tzone.period_for_local(t).abbreviation.to_s : + nil + + "(secs:#{seconds},utc~:#{ts.inspect},ltz~:#{z.inspect})" + end + def platform_info etos = Proc.new { |k, v| "#{k}:#{v.inspect}" } '(' + @@ -171,23 +196,56 @@ 'tzid' => defined?(TZInfo::Data), 'rv' => RUBY_VERSION, 'rp' => RUBY_PLATFORM, 'eov' => EtOrbi::VERSION, 'rorv' => (Rails::VERSION::STRING rescue nil), - 'astz' => Time.respond_to?(:zone) ? Time.zone.name : nil, - # Active Support Time.zone + 'astz' => ([ Time.zone.class, Time.zone.tzinfo.name ] rescue nil), }.collect(&etos).join(',') + ',' + gather_tzs.collect(&etos).join(',') + ')' end alias make make_time + + # For `make info` + # + def _make_info + + puts render_nozone_time(Time.now.to_f) + puts platform_info + end + + protected + + def get_local_tzone(t) + +# lt = local_tzone +# lp = lt.period_for_local(t) +# ab = lp.abbreviation.to_s +# +# return lt \ +# if ab == t.zone +# return lt \ +# if ab.match(/\A[-+]\d{2}(:?\d{2})?\z/) && lp.utc_offset == t.utc_offset +# +# nil + + l = Time.local(t.year, t.month, t.day, t.hour, t.min, t.sec, t.usec) + + t.zone == l.zone ? local_tzone : nil + end end + # Our EoTime class (which quacks like a ::Time). # - # 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. + # class EoTime # # class methods @@ -235,12 +293,12 @@ @seconds = s.to_f @zone = self.class.get_tzone(zone || :local) fail ArgumentError.new( "cannot determine timezone from #{zone.inspect}" + - "\n#{render_nozone_time(s)}" + - "\n#{self.class.platform_info.sub(',debian:', ",\ndebian:")}" + + "\n#{EtOrbi.render_nozone_time(s)}" + + "\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 @@ -257,26 +315,29 @@ @time = nil @zone = self.class.get_tzone(zone || :current) end + # Returns this ::EtOrbi::EoTime as a ::Time instance + # in the current UTC timezone. + # def utc Time.utc(1970, 1, 1) + @seconds end + # Returns true if this ::EtOrbi::EoTime instance timezone is UTC. + # Returns false else. + # def utc? %w[ zulu utc gmt ].include?(@zone.canonical_identifier.downcase) - - #t = Time.now - #@zone.period_for_local(t).utc_offset == 0 && - #@zone.period_for_local(t + 183 * 24 * 3600).utc_offset == 0 end alias getutc utc alias getgm utc + alias to_utc_time utc def to_f @seconds end @@ -291,19 +352,22 @@ format = format.gsub(/%(\/?Z|:{0,2}z)/) { |f| strfz(f) } to_time.strftime(format) end - # Returns a Ruby Time instance. + # Returns this ::EtOrbi::EoTime as a ::Time instance + # in the current timezone. # - # Warning: the timezone of that Time instance will be UTC. + # Has a #to_t alias. # - def to_time + def to_local_time - @time ||= begin; u = utc; @zone.period_for_utc(u).to_local(u); end + Time.at(@seconds) end + alias to_t to_local_time + def is_dst? @zone.period_for_utc(utc).std_offset != 0 end alias isdst is_dst? @@ -323,13 +387,10 @@ ].join(' ') end def utc_offset - #@zone.period_for_utc(utc).utc_offset - #@zone.period_for_utc(utc).utc_total_offset - #@zone.period_for_utc(utc).std_offset @zone.period_for_utc(utc).utc_offset end %w[ year month day wday hour min sec usec asctime @@ -338,13 +399,15 @@ end def iso8601(fraction_digits=0); to_time.iso8601(fraction_digits); end def ==(o) - o.is_a?(EoTime) && o.seconds == @seconds && o.zone == @zone + o.is_a?(EoTime) && + o.seconds == @seconds && + (o.zone == @zone || o.zone.current_period == @zone.current_period) end - #alias eq? == # FIXME see Object#== (ri) + #alias eql? == # FIXME see Object#== (ri) def >(o); @seconds > _to_f(o); end def >=(o); @seconds >= _to_f(o); end def <(o); @seconds < _to_f(o); end def <=(o); @seconds <= _to_f(o); end @@ -434,10 +497,19 @@ [ count_weeks(-1), - count_weeks(1) ] end protected + # Returns a Ruby Time instance. + # + # Warning: the timezone of that Time instance will be UTC. + # + def to_time + + @time ||= begin; u = utc; @zone.period_for_utc(u).to_local(u); end + end + def count_weeks(dir) c = 0 t = self until t.month != self.month @@ -446,25 +518,10 @@ end c end - def render_nozone_time(seconds) - - t = - Time.utc(0) + seconds - ts = - t.strftime('%Y-%m-%d %H:%M:%S') + - ".#{(seconds % 1).to_s.split('.').last}" - z = - EtOrbi.local_tzone ? - EtOrbi.local_tzone.period_for_local(t).abbreviation.to_s : - nil - - "(secs:#{seconds},utc~:#{ts.inspect},ltz~:#{z.inspect})" - end - def strfz(code) return @zone.name if code == '%/Z' per = @zone.period_for_utc(utc) @@ -547,19 +604,27 @@ etz = ENV['TZ'] tz = ::TZInfo::Timezone.get(etz) rescue nil return tz if tz - tz = Time.zone.tzinfo \ - if Time.respond_to?(:zone) && Time.zone.respond_to?(:tzinfo) + if Time.respond_to?(:zone) && Time.zone.respond_to?(:tzinfo) + tz = Time.zone.tzinfo + return tz if tz + end + + tz = ::TZInfo::Timezone.get(os_tz) rescue nil return tz if tz tzs = determine_local_tzones - (etz && tzs.find { |z| z.name == etz }) || tzs.first end + def os_tz + + debian_tz || centos_tz || osx_tz + end + # # protected module methods protected @@ -651,14 +716,9 @@ File.symlink?(path) ? File.readlink(path).split('/')[4..-1].join('/') : nil rescue; nil; end - -# def find_tz -# -# debian_tz || centos_tz || osx_tz -# end def gather_tzs { :debian => debian_tz, :centos => centos_tz, :osx => osx_tz } end