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