et-orbi 1.1.7 → 1.1.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/Makefile +4 -1
- data/README.md +1 -0
- data/lib/et-orbi.rb +6 -501
- data/lib/et-orbi/info.rb +74 -0
- data/lib/et-orbi/make.rb +112 -0
- data/lib/et-orbi/{eo_time.rb → time.rb} +18 -4
- data/lib/et-orbi/zone.rb +132 -0
- data/lib/et-orbi/zones.rb +328 -0
- metadata +7 -4
- data/lib/et-orbi/zone_aliases.rb +0 -121
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65b5afb2d0d4f7f1865b20129ff6896d735452b9
|
4
|
+
data.tar.gz: 57b48b7cd3835dce5bdd50628d704928c34c27e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed22b3055df4153c0c24be1f96b06dfa953c0638acb09d571f0df359d468b30524e4c70e9d5b013097731542b1b941603f1d8507b7689bf39a281f2d27d32318
|
7
|
+
data.tar.gz: 99a5479d314b98484d64575d5a446b33c122af030f1643c9a40fc1b80846a56f411b0ca272b58255f18b7862be8699fd61df90a7b99ee956f5fd14534d0f7e1f
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
# CHANGELOG.md
|
3
3
|
|
4
4
|
|
5
|
+
## et-orbi 1.1.8 released 2019-04-11
|
6
|
+
|
7
|
+
- Work hard to make it work on Windows
|
8
|
+
- Implement EoTime#rweek and #rday (reference week, reference day)
|
9
|
+
- Alias EoTime#in_time_zone(zone) to #localtime(zone)
|
10
|
+
|
11
|
+
|
5
12
|
## et-orbi 1.1.7 released 2019-01-14
|
6
13
|
|
7
14
|
- Rework Chronic integration, prevent conflict with ActiveSupport Time.zone
|
data/Makefile
CHANGED
@@ -11,6 +11,9 @@ count_lines:
|
|
11
11
|
find spec -name "*_spec.rb" | xargs cat | ruby -e "p STDIN.readlines.count { |l| l = l.strip; l[0, 1] != '#' && l != '' }"
|
12
12
|
cl: count_lines
|
13
13
|
|
14
|
+
scan:
|
15
|
+
scan lib/**/*.rb
|
16
|
+
|
14
17
|
gemspec_validate:
|
15
18
|
@echo "---"
|
16
19
|
ruby -e "s = eval(File.read(Dir['*.gemspec'].first)); p s.validate"
|
@@ -45,5 +48,5 @@ info:
|
|
45
48
|
|
46
49
|
## done ##
|
47
50
|
|
48
|
-
.PHONY: count_lines gemspec_validate name cw build push spec info
|
51
|
+
.PHONY: count_lines scan gemspec_validate name cw build push spec info
|
49
52
|
|
data/README.md
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
[![Build Status](https://secure.travis-ci.org/floraison/et-orbi.svg)](http://travis-ci.org/floraison/et-orbi)
|
5
5
|
[![Build status](https://ci.appveyor.com/api/projects/status/6tbo9lk9qdor8ipl?svg=true)](https://ci.appveyor.com/project/jmettraux/et-orbi)
|
6
6
|
[![Gem Version](https://badge.fury.io/rb/et-orbi.svg)](http://badge.fury.io/rb/et-orbi)
|
7
|
+
[![Join the chat at https://gitter.im/floraison/fugit](https://badges.gitter.im/floraison/fugit.svg)](https://gitter.im/floraison/fugit?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
7
8
|
|
8
9
|
Time zones for [fugit](https://github.com/floraison/fugit) and for [rufus-scheduler](https://github.com/jmettraux/rufus-scheduler). Urbi et Orbi.
|
9
10
|
|
data/lib/et-orbi.rb
CHANGED
@@ -4,510 +4,15 @@ require 'time'
|
|
4
4
|
|
5
5
|
require 'tzinfo'
|
6
6
|
|
7
|
-
require 'et-orbi/
|
8
|
-
require 'et-orbi/
|
7
|
+
require 'et-orbi/info'
|
8
|
+
require 'et-orbi/make'
|
9
|
+
require 'et-orbi/time'
|
10
|
+
require 'et-orbi/zones'
|
11
|
+
require 'et-orbi/zone'
|
9
12
|
|
10
13
|
|
11
14
|
module EtOrbi
|
12
15
|
|
13
|
-
VERSION = '1.1.
|
14
|
-
|
15
|
-
#
|
16
|
-
# module methods
|
17
|
-
|
18
|
-
class << self
|
19
|
-
|
20
|
-
def now(zone=nil)
|
21
|
-
|
22
|
-
EoTime.new(Time.now.to_f, zone)
|
23
|
-
end
|
24
|
-
|
25
|
-
def parse(str, opts={})
|
26
|
-
|
27
|
-
str, str_zone = extract_zone(str)
|
28
|
-
|
29
|
-
if defined?(::Chronic) && t = ::Chronic.parse(str, opts)
|
30
|
-
|
31
|
-
str = [ t.strftime('%F %T'), str_zone ].compact.join(' ')
|
32
|
-
end
|
33
|
-
|
34
|
-
begin
|
35
|
-
DateTime.parse(str)
|
36
|
-
rescue
|
37
|
-
fail ArgumentError, "No time information in #{str.inspect}"
|
38
|
-
end
|
39
|
-
#end if RUBY_VERSION < '1.9.0'
|
40
|
-
#end if RUBY_VERSION < '2.0.0'
|
41
|
-
#
|
42
|
-
# is necessary since Time.parse('xxx') in Ruby < 1.9 yields `now`
|
43
|
-
|
44
|
-
zone =
|
45
|
-
opts[:zone] ||
|
46
|
-
get_tzone(str_zone) ||
|
47
|
-
determine_local_tzone
|
48
|
-
|
49
|
-
local = Time.parse(str)
|
50
|
-
secs = zone.local_to_utc(local).to_f
|
51
|
-
|
52
|
-
EoTime.new(secs, zone)
|
53
|
-
end
|
54
|
-
|
55
|
-
def make_time(*a)
|
56
|
-
|
57
|
-
zone = a.length > 1 ? get_tzone(a.last) : nil
|
58
|
-
a.pop if zone
|
59
|
-
|
60
|
-
o = a.length > 1 ? a : a.first
|
61
|
-
|
62
|
-
case o
|
63
|
-
when Time then make_from_time(o, zone)
|
64
|
-
when Date then make_from_date(o, zone)
|
65
|
-
when Array then make_from_array(o, zone)
|
66
|
-
when String then make_from_string(o, zone)
|
67
|
-
when Numeric then make_from_numeric(o, zone)
|
68
|
-
when ::EtOrbi::EoTime then make_from_eotime(o, zone)
|
69
|
-
else fail ArgumentError.new(
|
70
|
-
"Cannot turn #{o.inspect} to a ::EtOrbi::EoTime instance")
|
71
|
-
end
|
72
|
-
end
|
73
|
-
alias make make_time
|
74
|
-
|
75
|
-
def make_from_time(t, zone)
|
76
|
-
|
77
|
-
z =
|
78
|
-
zone ||
|
79
|
-
get_as_tzone(t) ||
|
80
|
-
get_tzone(t.zone) ||
|
81
|
-
get_local_tzone(t)
|
82
|
-
|
83
|
-
z ||= t.zone
|
84
|
-
# pass the abbreviation anyway,
|
85
|
-
# it will be used in the resulting error message
|
86
|
-
|
87
|
-
EoTime.new(t, z)
|
88
|
-
end
|
89
|
-
|
90
|
-
def make_from_date(d, zone)
|
91
|
-
|
92
|
-
make_from_time(
|
93
|
-
d.respond_to?(:to_time) ?
|
94
|
-
d.to_time :
|
95
|
-
Time.parse(d.strftime('%Y-%m-%d %H:%M:%S')),
|
96
|
-
zone)
|
97
|
-
end
|
98
|
-
|
99
|
-
def make_from_array(a, zone)
|
100
|
-
|
101
|
-
t = Time.utc(*a)
|
102
|
-
s = t.strftime("%Y-%m-%d %H:%M:%S.#{'%06d' % t.usec}")
|
103
|
-
|
104
|
-
make_from_string(s, zone)
|
105
|
-
end
|
106
|
-
|
107
|
-
def make_from_string(s, zone)
|
108
|
-
|
109
|
-
parse(s, zone: zone)
|
110
|
-
end
|
111
|
-
|
112
|
-
def make_from_numeric(f, zone)
|
113
|
-
|
114
|
-
EoTime.new(Time.now.to_f + f, zone)
|
115
|
-
end
|
116
|
-
|
117
|
-
def make_from_eotime(eot, zone)
|
118
|
-
|
119
|
-
return eot if zone == nil || zone == eot.zone
|
120
|
-
EoTime.new(eot.to_f, zone)
|
121
|
-
end
|
122
|
-
|
123
|
-
def get_tzone(o)
|
124
|
-
|
125
|
-
return o if o.is_a?(::TZInfo::Timezone)
|
126
|
-
return nil if o == nil
|
127
|
-
return determine_local_tzone if o == :local
|
128
|
-
return ::TZInfo::Timezone.get('Zulu') if o == 'Z'
|
129
|
-
return o.tzinfo if o.respond_to?(:tzinfo)
|
130
|
-
|
131
|
-
o = to_offset(o) if o.is_a?(Numeric)
|
132
|
-
|
133
|
-
return nil unless o.is_a?(String)
|
134
|
-
|
135
|
-
s = unalias(o)
|
136
|
-
|
137
|
-
get_offset_tzone(s) ||
|
138
|
-
get_x_offset_tzone(s) ||
|
139
|
-
(::TZInfo::Timezone.get(s) rescue nil)
|
140
|
-
end
|
141
|
-
|
142
|
-
def render_nozone_time(seconds)
|
143
|
-
|
144
|
-
t =
|
145
|
-
Time.utc(1970) + seconds
|
146
|
-
ts =
|
147
|
-
t.strftime('%Y-%m-%d %H:%M:%S') +
|
148
|
-
".#{(seconds % 1).to_s.split('.').last}"
|
149
|
-
tz =
|
150
|
-
EtOrbi.determine_local_tzone
|
151
|
-
z =
|
152
|
-
tz ? tz.period_for_local(t).abbreviation.to_s : nil
|
153
|
-
|
154
|
-
"(secs:#{seconds},utc~:#{ts.inspect},ltz~:#{z.inspect})"
|
155
|
-
end
|
156
|
-
|
157
|
-
def tzinfo_version
|
158
|
-
|
159
|
-
#TZInfo::VERSION
|
160
|
-
Gem.loaded_specs['tzinfo'].version.to_s
|
161
|
-
rescue => err
|
162
|
-
err.inspect
|
163
|
-
end
|
164
|
-
|
165
|
-
def tzinfo_data_version
|
166
|
-
|
167
|
-
#TZInfo::Data::VERSION rescue nil
|
168
|
-
Gem.loaded_specs['tzinfo-data'].version.to_s rescue nil
|
169
|
-
end
|
170
|
-
|
171
|
-
def platform_info
|
172
|
-
|
173
|
-
etos = Proc.new { |k, v| "#{k}:#{v.inspect}" }
|
174
|
-
|
175
|
-
h = {
|
176
|
-
'etz' => ENV['TZ'],
|
177
|
-
'tnz' => Time.now.zone,
|
178
|
-
'tziv' => tzinfo_version,
|
179
|
-
'tzidv' => tzinfo_data_version,
|
180
|
-
'rv' => RUBY_VERSION,
|
181
|
-
'rp' => RUBY_PLATFORM,
|
182
|
-
'win' => Gem.win_platform?,
|
183
|
-
'rorv' => (Rails::VERSION::STRING rescue nil),
|
184
|
-
'astz' => ([ Time.zone.class, Time.zone.tzinfo.name ] rescue nil),
|
185
|
-
'eov' => EtOrbi::VERSION,
|
186
|
-
'eotnz' => '???',
|
187
|
-
'eotnfz' => '???',
|
188
|
-
'eotlzn' => '???' }
|
189
|
-
if ltz = EtOrbi::EoTime.local_tzone
|
190
|
-
h['eotnz'] = EtOrbi::EoTime.now.zone
|
191
|
-
h['eotnfz'] = EtOrbi::EoTime.now.strftime('%z')
|
192
|
-
h['eotnfZ'] = EtOrbi::EoTime.now.strftime('%Z')
|
193
|
-
h['eotlzn'] = ltz.name
|
194
|
-
end
|
195
|
-
|
196
|
-
"(#{h.map(&etos).join(',')},#{gather_tzs.map(&etos).join(',')})"
|
197
|
-
end
|
198
|
-
|
199
|
-
# For `make info`
|
200
|
-
#
|
201
|
-
def _make_info
|
202
|
-
|
203
|
-
puts render_nozone_time(Time.now.to_f)
|
204
|
-
puts platform_info
|
205
|
-
end
|
206
|
-
|
207
|
-
ZONES_ISO8601 =
|
208
|
-
%r{
|
209
|
-
(?<=:\d\d)\s*
|
210
|
-
(?:
|
211
|
-
[-+]
|
212
|
-
(?:[0-1][0-9]|2[0-4])
|
213
|
-
(?:(?::)?(?:[0-5][0-9]|60))?
|
214
|
-
(?![-+])
|
215
|
-
|Z
|
216
|
-
)
|
217
|
-
}x
|
218
|
-
|
219
|
-
# https://en.wikipedia.org/wiki/ISO_8601
|
220
|
-
# Postel's law applies
|
221
|
-
#
|
222
|
-
def list_iso8601_zones(s)
|
223
|
-
|
224
|
-
s.scan(ZONES_ISO8601).collect(&:strip)
|
225
|
-
end
|
226
|
-
|
227
|
-
ZONES_OLSON = (
|
228
|
-
TZInfo::Timezone.all.collect { |z| z.name }.sort +
|
229
|
-
(0..12).collect { |i| [ "UTC-#{i}", "UTC+#{i}" ] })
|
230
|
-
.flatten
|
231
|
-
.sort_by(&:size)
|
232
|
-
.reverse
|
233
|
-
|
234
|
-
def list_olson_zones(s)
|
235
|
-
|
236
|
-
s = s.dup
|
237
|
-
|
238
|
-
ZONES_OLSON
|
239
|
-
.inject([]) { |a, z|
|
240
|
-
i = s.index(z); next a unless i
|
241
|
-
s[i, z.length] = ''
|
242
|
-
a << z
|
243
|
-
a }
|
244
|
-
end
|
245
|
-
|
246
|
-
def find_olson_zone(str)
|
247
|
-
|
248
|
-
list_olson_zones(str).each { |s| z = get_tzone(s); return z if z }
|
249
|
-
nil
|
250
|
-
end
|
251
|
-
|
252
|
-
def extract_zone(str)
|
253
|
-
|
254
|
-
s = str.dup
|
255
|
-
|
256
|
-
zs = ZONES_OLSON
|
257
|
-
.inject([]) { |a, z|
|
258
|
-
i = s.index(z); next a unless i
|
259
|
-
a << z
|
260
|
-
s[i, z.length] = ''
|
261
|
-
a }
|
262
|
-
|
263
|
-
s.gsub!(ZONES_ISO8601) { |m| zs << m.strip; '' } #if zs.empty?
|
264
|
-
|
265
|
-
zs = zs.sort_by { |z| str.index(z) }
|
266
|
-
|
267
|
-
[ s.strip, zs.last ]
|
268
|
-
end
|
269
|
-
|
270
|
-
def determine_local_tzone
|
271
|
-
|
272
|
-
# ENV has the priority
|
273
|
-
|
274
|
-
etz = ENV['TZ']
|
275
|
-
|
276
|
-
tz = etz && get_tzone(etz)
|
277
|
-
return tz if tz
|
278
|
-
|
279
|
-
# then Rails/ActiveSupport has the priority
|
280
|
-
|
281
|
-
if Time.respond_to?(:zone) && Time.zone.respond_to?(:tzinfo)
|
282
|
-
tz = Time.zone.tzinfo
|
283
|
-
return tz if tz
|
284
|
-
end
|
285
|
-
|
286
|
-
# then the operating system is queried
|
287
|
-
|
288
|
-
tz = ::TZInfo::Timezone.get(os_tz) rescue nil
|
289
|
-
return tz if tz
|
290
|
-
|
291
|
-
# then Ruby's time zone abbs are looked at CST, JST, CEST, ... :-(
|
292
|
-
|
293
|
-
tzs = determine_local_tzones
|
294
|
-
tz = (etz && tzs.find { |z| z.name == etz }) || tzs.first
|
295
|
-
return tz if tz
|
296
|
-
|
297
|
-
# then, fall back to GMT offest :-(
|
298
|
-
|
299
|
-
n = Time.now
|
300
|
-
|
301
|
-
get_tzone(n.zone) ||
|
302
|
-
get_tzone(n.strftime('%Z%z'))
|
303
|
-
end
|
304
|
-
alias zone determine_local_tzone
|
305
|
-
|
306
|
-
attr_accessor :_os_zone # test tool
|
307
|
-
|
308
|
-
def os_tz
|
309
|
-
|
310
|
-
return (@_os_zone == '' ? nil : @_os_zone) \
|
311
|
-
if defined?(@_os_zone) && @_os_zone
|
312
|
-
|
313
|
-
@os_tz ||= (debian_tz || centos_tz || osx_tz)
|
314
|
-
end
|
315
|
-
|
316
|
-
# Semi-helpful, since it requires the current time
|
317
|
-
#
|
318
|
-
def windows_zone_name(zone_name, time)
|
319
|
-
|
320
|
-
twin = Time.utc(time.year, 1, 1) # winter
|
321
|
-
tsum = Time.utc(time.year, 7, 1) # summer
|
322
|
-
|
323
|
-
tz = ::TZInfo::Timezone.get(zone_name)
|
324
|
-
tzo = tz.period_for_local(time).utc_total_offset
|
325
|
-
tzop = tzo < 0 ? nil : '-'; tzo = tzo.abs
|
326
|
-
tzoh = tzo / 3600
|
327
|
-
tzos = tzo % 3600
|
328
|
-
tzos = tzos == 0 ? nil : ':%02d' % (tzos / 60)
|
329
|
-
|
330
|
-
abbs = [
|
331
|
-
tz.period_for_utc(twin).abbreviation.to_s,
|
332
|
-
tz.period_for_utc(tsum).abbreviation.to_s ]
|
333
|
-
.uniq
|
334
|
-
|
335
|
-
if abbs[0].match(/\A[A-Z]/)
|
336
|
-
[ abbs[0], tzop, tzoh, tzos, abbs[1] ]
|
337
|
-
.compact.join
|
338
|
-
else
|
339
|
-
[ windows_zone_code_x(zone_name), tzop, tzoh, tzos || ':00', zone_name ]
|
340
|
-
.collect(&:to_s).join
|
341
|
-
end
|
342
|
-
end
|
343
|
-
|
344
|
-
#
|
345
|
-
# protected module methods
|
346
|
-
|
347
|
-
protected
|
348
|
-
|
349
|
-
def windows_zone_code_x(zone_name)
|
350
|
-
|
351
|
-
a = [ '_' ]
|
352
|
-
a.concat(zone_name.split('/')[0, 2].collect { |s| s[0, 1].upcase })
|
353
|
-
a << '_' if a.size < 3
|
354
|
-
|
355
|
-
a.join
|
356
|
-
end
|
357
|
-
|
358
|
-
def get_local_tzone(t)
|
359
|
-
|
360
|
-
l = Time.local(t.year, t.month, t.day, t.hour, t.min, t.sec, t.usec)
|
361
|
-
|
362
|
-
(t.zone == l.zone) ? determine_local_tzone : nil
|
363
|
-
end
|
364
|
-
|
365
|
-
# https://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html
|
366
|
-
#
|
367
|
-
# If it responds to #time_zone, then return that time zone.
|
368
|
-
#
|
369
|
-
def get_as_tzone(t)
|
370
|
-
|
371
|
-
t.respond_to?(:time_zone) ? t.time_zone : nil
|
372
|
-
end
|
373
|
-
|
374
|
-
def to_offset(n)
|
375
|
-
|
376
|
-
i = n.to_i
|
377
|
-
sn = i < 0 ? '-' : '+'; i = i.abs
|
378
|
-
hr = i / 3600; mn = i % 3600; sc = i % 60
|
379
|
-
|
380
|
-
sc > 0 ?
|
381
|
-
'%s%02d:%02d:%02d' % [ sn, hr, mn, sc ] :
|
382
|
-
'%s%02d:%02d' % [ sn, hr, mn ]
|
383
|
-
end
|
384
|
-
|
385
|
-
# custom timezones, no DST, just an offset, like "+08:00" or "-01:30"
|
386
|
-
#
|
387
|
-
def get_offset_tzone(str)
|
388
|
-
|
389
|
-
m = str.match(/\A([+-][0-1]?[0-9]):?([0-5][0-9])?\z/) rescue nil
|
390
|
-
#
|
391
|
-
# On Windows, the real encoding could be something other than UTF-8,
|
392
|
-
# and make the match fail
|
393
|
-
#
|
394
|
-
return nil unless m
|
395
|
-
|
396
|
-
tz = custom_tzs[str]
|
397
|
-
return tz if tz
|
398
|
-
|
399
|
-
hr = m[1].to_i
|
400
|
-
mn = m[2].to_i
|
401
|
-
|
402
|
-
hr = nil if hr.abs > 11
|
403
|
-
hr = nil if mn > 59
|
404
|
-
mn = -mn if hr && hr < 0
|
405
|
-
|
406
|
-
hr ?
|
407
|
-
custom_tzs[str] = create_offset_tzone(hr * 3600 + mn * 60, str) :
|
408
|
-
nil
|
409
|
-
end
|
410
|
-
|
411
|
-
if defined?(TZInfo::DataSources::ConstantOffsetDataTimezoneInfo)
|
412
|
-
# TZInfo >= 2.0.0
|
413
|
-
|
414
|
-
def create_offset_tzone(utc_off, id)
|
415
|
-
|
416
|
-
off = TZInfo::TimezoneOffset.new(utc_off, 0, id)
|
417
|
-
tzi = TZInfo::DataSources::ConstantOffsetDataTimezoneInfo.new(id, off)
|
418
|
-
tzi.create_timezone
|
419
|
-
end
|
420
|
-
|
421
|
-
else
|
422
|
-
# TZInfo < 2.0.0
|
423
|
-
|
424
|
-
def create_offset_tzone(utc_off, id)
|
425
|
-
|
426
|
-
tzi = TZInfo::TransitionDataTimezoneInfo.new(id)
|
427
|
-
tzi.offset(id, utc_off, 0, id)
|
428
|
-
tzi.create_timezone
|
429
|
-
end
|
430
|
-
end
|
431
|
-
|
432
|
-
def get_x_offset_tzone(str)
|
433
|
-
|
434
|
-
m = str.match(/\A_..-?[0-1]?\d:?(?:[0-5]\d)?(.+)\z/) rescue nil
|
435
|
-
#
|
436
|
-
# On Windows, the real encoding could be something other than UTF-8,
|
437
|
-
# and make the match fail (as in .get_offset_tzone above)
|
438
|
-
|
439
|
-
m ? ::TZInfo::Timezone.get(m[1]) : nil
|
440
|
-
end
|
441
|
-
|
442
|
-
def determine_local_tzones
|
443
|
-
|
444
|
-
tabbs = (-6..5)
|
445
|
-
.collect { |i|
|
446
|
-
t = Time.now + i * 30 * 24 * 3600
|
447
|
-
"#{t.zone}_#{t.utc_offset}" }
|
448
|
-
.uniq
|
449
|
-
.sort
|
450
|
-
.join('|')
|
451
|
-
|
452
|
-
t = Time.now
|
453
|
-
#tu = t.dup.utc # /!\ dup is necessary, #utc modifies its target
|
454
|
-
|
455
|
-
twin = Time.local(t.year, 1, 1) # winter
|
456
|
-
tsum = Time.local(t.year, 7, 1) # summer
|
457
|
-
|
458
|
-
@tz_winter_summer ||= {}
|
459
|
-
|
460
|
-
@tz_winter_summer[tabbs] ||= tz_all
|
461
|
-
.select { |tz|
|
462
|
-
pw = tz.period_for_local(twin)
|
463
|
-
ps = tz.period_for_local(tsum)
|
464
|
-
tabbs ==
|
465
|
-
[ "#{pw.abbreviation}_#{pw.utc_total_offset}",
|
466
|
-
"#{ps.abbreviation}_#{ps.utc_total_offset}" ]
|
467
|
-
.uniq.sort.join('|') }
|
468
|
-
|
469
|
-
@tz_winter_summer[tabbs]
|
470
|
-
end
|
471
|
-
|
472
|
-
def custom_tzs; @custom_tzs ||= {}; end
|
473
|
-
def tz_all; @tz_all ||= ::TZInfo::Timezone.all; end
|
474
|
-
|
475
|
-
#
|
476
|
-
# system tz determination
|
477
|
-
|
478
|
-
def debian_tz
|
479
|
-
|
480
|
-
path = '/etc/timezone'
|
481
|
-
|
482
|
-
File.exist?(path) ? File.read(path).strip : nil
|
483
|
-
rescue; nil; end
|
484
|
-
|
485
|
-
def centos_tz
|
486
|
-
|
487
|
-
path = '/etc/sysconfig/clock'
|
488
|
-
|
489
|
-
File.open(path, 'rb') do |f|
|
490
|
-
until f.eof?
|
491
|
-
if m = f.readline.match(/ZONE="([^"]+)"/); return m[1]; end
|
492
|
-
end
|
493
|
-
end if File.exist?(path)
|
494
|
-
|
495
|
-
nil
|
496
|
-
rescue; nil; end
|
497
|
-
|
498
|
-
def osx_tz
|
499
|
-
|
500
|
-
path = '/etc/localtime'
|
501
|
-
|
502
|
-
File.symlink?(path) ?
|
503
|
-
File.readlink(path).split('/')[4..-1].join('/') :
|
504
|
-
nil
|
505
|
-
rescue; nil; end
|
506
|
-
|
507
|
-
def gather_tzs
|
508
|
-
|
509
|
-
{ :debian => debian_tz, :centos => centos_tz, :osx => osx_tz }
|
510
|
-
end
|
511
|
-
end
|
16
|
+
VERSION = '1.1.8'
|
512
17
|
end
|
513
18
|
|