Module: EtOrbi
- Defined in:
- lib/et-orbi.rb,
lib/et-orbi/info.rb,
lib/et-orbi/make.rb,
lib/et-orbi/time.rb,
lib/et-orbi/zone.rb,
lib/et-orbi/zones.rb
Defined Under Namespace
Classes: EoTime
Constant Summary collapse
- VERSION =
'1.2.11'
- ZONES_ISO8601_REX =
%r{ (?<=:\d\d)\s* (?: [-+] (?:[0-1][0-9]|2[0-4]) (?:(?::)?(?:[0-5][0-9]|60))? (?![-+]) |Z ) }x.freeze
- ZONES_OLSON =
( ::TZInfo::Timezone.all .collect { |z| z.name }.sort + (0..12) .collect { |i| [ "UTC-#{i}", "UTC+#{i}" ] }) .flatten .sort_by(&:size) .reverse
- ZONE_ALIASES =
{ 'Coordinated Universal Time' => 'UTC', 'Afghanistan Standard Time' => 'Asia/Kabul', 'FLE Standard Time' => 'Europe/Helsinki', 'Central Europe Standard Time' => 'Europe/Prague', 'UTC-11' => 'Etc/GMT+11', 'W. Europe Standard Time' => 'Europe/Rome', 'W. Central Africa Standard Time' => 'Africa/Lagos', 'SA Western Standard Time' => 'America/La_Paz', 'Pacific SA Standard Time' => 'America/Santiago', 'Argentina Standard Time' => 'America/Argentina/Buenos_Aires', 'Caucasus Standard Time' => 'Asia/Yerevan', 'AUS Eastern Standard Time' => 'Australia/Sydney', 'Azerbaijan Standard Time' => 'Asia/Baku', 'Eastern Standard Time' => 'America/New_York', 'Arab Standard Time' => 'Asia/Riyadh', 'Bangladesh Standard Time' => 'Asia/Dhaka', 'Belarus Standard Time' => 'Europe/Minsk', 'Romance Standard Time' => 'Europe/Paris', 'Central America Standard Time' => 'America/Belize', 'Atlantic Standard Time' => 'Atlantic/Bermuda', 'Venezuela Standard Time' => 'America/Caracas', 'Central European Standard Time' => 'Europe/Warsaw', 'South Africa Standard Time' => 'Africa/Johannesburg', #'UTC' => 'Etc/UTC', # 'UTC' is good as is 'E. South America Standard Time' => 'America/Sao_Paulo', 'Central Asia Standard Time' => 'Asia/Almaty', 'Singapore Standard Time' => 'Asia/Singapore', 'Greenwich Standard Time' => 'Africa/Monrovia', 'Cape Verde Standard Time' => 'Atlantic/Cape_Verde', 'SE Asia Standard Time' => 'Asia/Bangkok', 'SA Pacific Standard Time' => 'America/Bogota', 'China Standard Time' => 'Asia/Shanghai', 'Myanmar Standard Time' => 'Asia/Yangon', 'E. Africa Standard Time' => 'Africa/Nairobi', 'Hawaiian Standard Time' => 'Pacific/Honolulu', 'E. Europe Standard Time' => 'Europe/Nicosia', 'Tokyo Standard Time' => 'Asia/Tokyo', 'Egypt Standard Time' => 'Africa/Cairo', 'SA Eastern Standard Time' => 'America/Cayenne', 'GMT Standard Time' => 'Europe/London', 'Fiji Standard Time' => 'Pacific/Fiji', 'West Asia Standard Time' => 'Asia/Tashkent', 'Georgian Standard Time' => 'Asia/Tbilisi', 'GTB Standard Time' => 'Europe/Athens', 'Greenland Standard Time' => 'America/Godthab', 'West Pacific Standard Time' => 'Pacific/Guam', 'Mauritius Standard Time' => 'Indian/Mauritius', 'India Standard Time' => 'Asia/Kolkata', 'Iran Standard Time' => 'Asia/Tehran', 'Arabic Standard Time' => 'Asia/Baghdad', 'Israel Standard Time' => 'Asia/Jerusalem', 'Jordan Standard Time' => 'Asia/Amman', 'UTC+12' => 'Etc/GMT-12', 'Korea Standard Time' => 'Asia/Seoul', 'Middle East Standard Time' => 'Asia/Beirut', 'Central Standard Time (Mexico)' => 'America/Mexico_City', 'Ulaanbaatar Standard Time' => 'Asia/Ulaanbaatar', 'Morocco Standard Time' => 'Africa/Casablanca', 'Namibia Standard Time' => 'Africa/Windhoek', 'Nepal Standard Time' => 'Asia/Kathmandu', 'Central Pacific Standard Time' => 'Etc/GMT-11', 'New Zealand Standard Time' => 'Pacific/Auckland', 'Arabian Standard Time' => 'Asia/Dubai', 'Pakistan Standard Time' => 'Asia/Karachi', 'Paraguay Standard Time' => 'America/Asuncion', 'Pacific Standard Time' => 'America/Los_Angeles', 'Russian Standard Time' => 'Europe/Moscow', 'Samoa Standard Time' => 'Pacific/Pago_Pago', 'UTC-02' => 'Etc/GMT+2', 'Sri Lanka Standard Time' => 'Asia/Kolkata', 'Syria Standard Time' => 'Asia/Damascus', 'Taipei Standard Time' => 'Asia/Taipei', 'Tonga Standard Time' => 'Pacific/Tongatapu', 'Turkey Standard Time' => 'Asia/Istanbul', 'Montevideo Standard Time' => 'America/Montevideo', 'CST5CDT' => 'CST6CDT', 'Alaskan Standard Time' => 'America/Anchorage', 'Central Standard Time' => 'America/Chicago', 'Mountain Standard Time' => 'America/Denver', 'US Eastern Standard Time' => 'America/Indiana/Indianapolis', 'US Mountain Standard Time' => 'America/Phoenix' }
Class Attribute Summary collapse
-
._os_zone ⇒ Object
test tool.
Class Method Summary collapse
-
._make_info ⇒ Object
For ‘make info`.
- .centos_tz ⇒ Object
- .chronic_enabled=(b) ⇒ Object
- .chronic_enabled? ⇒ Boolean
-
.debian_tz ⇒ Object
system tz determination.
- .determine_local_tzone ⇒ Object (also: zone)
- .extract_zone(str) ⇒ Object
- .gather_tzs ⇒ Object
- .get_tzone(o) ⇒ Object
-
.list_iso8601_zones(s) ⇒ Object
en.wikipedia.org/wiki/ISO_8601 Postel’s law applies.
- .make_time(*a) ⇒ Object (also: make)
- .now(zone = nil) ⇒ Object
- .os_tz ⇒ Object
- .osx_tz ⇒ Object
- .parse(str, opts = {}) ⇒ Object
- .platform_info ⇒ Object
- .render_nozone_time(seconds) ⇒ Object
- .tweak_zone_name(name) ⇒ Object
-
.windows_zone_name(zone_name, time) ⇒ Object
Semi-helpful, since it requires the current time.
Class Attribute Details
._os_zone ⇒ Object
test tool
89 90 91 |
# File 'lib/et-orbi/zones.rb', line 89 def _os_zone @_os_zone end |
Class Method Details
._make_info ⇒ Object
For ‘make info`
36 37 38 39 40 |
# File 'lib/et-orbi/info.rb', line 36 def _make_info puts render_nozone_time(Time.now.to_f) puts platform_info end |
.centos_tz ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/et-orbi/zones.rb', line 109 def centos_tz path = '/etc/sysconfig/clock' File.open(path, 'rb') do |f| until f.eof? if m = f.readline.match(/ZONE="([^"]+)"/); return m[1]; end end end if File.exist?(path) nil rescue; nil; end |
.chronic_enabled=(b) ⇒ Object
9 10 11 |
# File 'lib/et-orbi/make.rb', line 9 def self.chronic_enabled=(b) @chronic_enabled = b end |
.chronic_enabled? ⇒ Boolean
6 7 8 |
# File 'lib/et-orbi/make.rb', line 6 def self.chronic_enabled? @chronic_enabled end |
.debian_tz ⇒ Object
system tz determination
102 103 104 105 106 107 |
# File 'lib/et-orbi/zones.rb', line 102 def debian_tz path = '/etc/timezone' File.exist?(path) ? File.read(path).strip : nil rescue; nil; end |
.determine_local_tzone ⇒ Object Also known as: zone
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/et-orbi/zones.rb', line 53 def determine_local_tzone # ENV has the priority etz = ENV['TZ'] tz = etz && get_tzone(etz) return tz if tz # then Rails/ActiveSupport has the priority if Time.respond_to?(:zone) && Time.zone.respond_to?(:tzinfo) tz = Time.zone.tzinfo return tz if tz end # then the operating system is queried tz = ::TZInfo::Timezone.get(os_tz) rescue nil return tz if tz # then Ruby's time zone abbs are looked at CST, JST, CEST, ... :-( tzs = determine_local_tzones tz = (etz && tzs.find { |z| z.name == etz }) || tzs.first return tz if tz # then, fall back to GMT offest :-( n = Time.now get_tzone(n.zone) || get_tzone(n.strftime('%Z%z')) end |
.extract_zone(str) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/et-orbi/zones.rb', line 35 def extract_zone(str) s = str.dup zs = ZONES_OLSON .inject([]) { |a, z| i = s.index(z); next a unless i a << z s[i, z.length] = '' a } s.gsub!(ZONES_ISO8601_REX) { |m| zs << m.strip; '' } #if zs.empty? zs = zs.sort_by { |z| str.index(z) } [ s.strip, zs.last ] end |
.gather_tzs ⇒ Object
131 132 133 134 |
# File 'lib/et-orbi/zones.rb', line 131 def gather_tzs { :debian => debian_tz, :centos => centos_tz, :osx => osx_tz } end |
.get_tzone(o) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/et-orbi/zone.rb', line 6 def get_tzone(o) return o if o.is_a?(::TZInfo::Timezone) return nil if o == nil return determine_local_tzone if o == :local return ::TZInfo::Timezone.get('Zulu') if o == 'Z' return o.tzinfo if o.respond_to?(:tzinfo) o = to_offset(o) if o.is_a?(Numeric) return nil unless o.is_a?(String) s = tweak_zone_name(o) get_offset_tzone(s) || get_x_offset_tzone(s) || get_tzinfo_tzone(s) end |
.list_iso8601_zones(s) ⇒ Object
en.wikipedia.org/wiki/ISO_8601 Postel’s law applies
21 22 23 24 |
# File 'lib/et-orbi/zones.rb', line 21 def list_iso8601_zones(s) s.scan(ZONES_ISO8601_REX).collect(&:strip) end |
.make_time(*a) ⇒ Object Also known as: make
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/et-orbi/make.rb', line 51 def make_time(*a) zone = a.length > 1 ? get_tzone(a.last) : nil a.pop if zone o = a.length > 1 ? a : a.first 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) when String then make_from_string(o, zone) when Numeric then make_from_numeric(o, zone) when ::EtOrbi::EoTime then make_from_eotime(o, zone) else fail ArgumentError.new( "Cannot turn #{o.inspect} to a ::EtOrbi::EoTime instance") end end |
.now(zone = nil) ⇒ Object
15 16 17 18 |
# File 'lib/et-orbi/make.rb', line 15 def now(zone=nil) EoTime.new(Time.now.to_f, zone) end |
.os_tz ⇒ Object
91 92 93 94 95 96 97 |
# File 'lib/et-orbi/zones.rb', line 91 def os_tz return (@_os_zone == '' ? nil : @_os_zone) \ if defined?(@_os_zone) && @_os_zone @os_tz ||= (debian_tz || centos_tz || osx_tz) end |
.osx_tz ⇒ Object
122 123 124 125 126 127 128 129 |
# File 'lib/et-orbi/zones.rb', line 122 def osx_tz path = '/etc/localtime' File.symlink?(path) ? File.readlink(path).split('/')[4..-1].join('/') : nil rescue; nil; end |
.parse(str, opts = {}) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/et-orbi/make.rb', line 20 def parse(str, opts={}) str, str_zone = extract_zone(str) if t = chronic_parse(str, opts) str = [ t.strftime('%F %T'), str_zone ].compact.join(' ') end dt = begin DateTime.parse(str) rescue fail ArgumentError, "No time information in #{str.inspect}" end #end if RUBY_VERSION < '1.9.0' #end if RUBY_VERSION < '2.0.0' # # is necessary since Time.parse('xxx') in Ruby < 1.9 yields `now` zone = opts[:zone] || get_tzone(str_zone) || determine_local_tzone #local = Time.parse(str) #secs = zone.local_to_utc(local).to_f secs = zone.local_to_utc(dt).to_time.to_f EoTime.new(secs, zone) end |
.platform_info ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/et-orbi/info.rb', line 6 def platform_info etos = Proc.new { |k, v| "#{k}:#{v.inspect}" } h = { 'etz' => ENV['TZ'], 'tnz' => Time.now.zone, 'tziv' => tzinfo_version, 'tzidv' => tzinfo_data_version, 'rv' => RUBY_VERSION, 'rp' => RUBY_PLATFORM, 'win' => Gem.win_platform?, 'rorv' => (Rails::VERSION::STRING rescue nil), 'astz' => ([ Time.zone.class, Time.zone.tzinfo.name ] rescue nil), 'eov' => EtOrbi::VERSION, 'eotnz' => '???', 'eotnfz' => '???', 'eotlzn' => '???' } if ltz = EtOrbi::EoTime.local_tzone h['eotnz'] = EtOrbi::EoTime.now.zone h['eotnfz'] = EtOrbi::EoTime.now.strftime('%z') h['eotnfZ'] = EtOrbi::EoTime.now.strftime('%Z') h['eotlzn'] = ltz.name end "(#{h.map(&etos).join(',')},#{gather_tzs.map(&etos).join(',')})" end |
.render_nozone_time(seconds) ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/et-orbi/info.rb', line 42 def render_nozone_time(seconds) t = Time.utc(1970) + seconds ts = t.strftime('%Y-%m-%d %H:%M:%S') + ".#{(seconds % 1).to_s.split('.').last}" tz = EtOrbi.determine_local_tzone z = tz ? tz.period_for_local(t).abbreviation.to_s : nil "(secs:#{seconds},utc~:#{ts.inspect},ltz~:#{z.inspect})" end |
.tweak_zone_name(name) ⇒ Object
164 165 166 167 168 169 170 171 172 |
# File 'lib/et-orbi/zones.rb', line 164 def tweak_zone_name(name) return name unless (name.match(/./) rescue nil) # to prevent invalid byte sequence in UTF-8..., gh-15 normalize(name) || unzz(name) || name end |
.windows_zone_name(zone_name, time) ⇒ Object
Semi-helpful, since it requires the current time
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/et-orbi/zones.rb', line 138 def windows_zone_name(zone_name, time) twin = Time.utc(time.year, 1, 1) # winter tsum = Time.utc(time.year, 7, 1) # summer tz = ::TZInfo::Timezone.get(zone_name) tzo = tz.period_for_local(time).utc_total_offset tzop = tzo < 0 ? nil : '-'; tzo = tzo.abs tzoh = tzo / 3600 tzos = tzo % 3600 tzos = tzos == 0 ? nil : ':%02d' % (tzos / 60) abbs = [ tz.period_for_utc(twin).abbreviation.to_s, tz.period_for_utc(tsum).abbreviation.to_s ] .uniq if abbs[0].match(/\A[A-Z]/) [ abbs[0], tzop, tzoh, tzos, abbs[1] ] .compact.join else [ windows_zone_code_x(zone_name), tzop, tzoh, tzos || ':00', zone_name ] .collect(&:to_s).join end end |