et-orbi 1.1.7 → 1.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
[](http://travis-ci.org/floraison/et-orbi)
|
|
5
5
|
[](https://ci.appveyor.com/project/jmettraux/et-orbi)
|
|
6
6
|
[](http://badge.fury.io/rb/et-orbi)
|
|
7
|
+
[](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
|
|