et-orbi 1.0.4 → 1.0.5
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 +12 -0
- data/README.md +3 -0
- data/lib/et-orbi.rb +342 -263
- metadata +14 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 69e37c4c31852fc38185e883d9c1cb061080eb6d
|
4
|
+
data.tar.gz: 1862219b63d16c1e79b681bd5f930a419f1da254
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5dcab4f70ec22ef0a7c8303b14042344860df2d26ca93fc27923a52b2a87aa36c671422f73be18d432a15524d60b86945c467c1b6fdda125f8408a8bf6e64f72
|
7
|
+
data.tar.gz: '07203989eedf55dbfbeb40b0433060e03644760d07a8448b78f7c30af1694b173fc67e507360262a316978815cf04181c45c0264634af75f37dd492397e56d01'
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,18 @@
|
|
2
2
|
# et-orbi CHANGELOG.md
|
3
3
|
|
4
4
|
|
5
|
+
## et-orbi 1.0.5 released 2017-06-23
|
6
|
+
|
7
|
+
- Rework EtOrbi.make_time
|
8
|
+
- Let EtOrbi.make_time accept array or array of args
|
9
|
+
- Implement EoTime#localtime(zone=nil)
|
10
|
+
- Move Fugit#wday_in_month into EoTime
|
11
|
+
- Clarify #add, #subtract, #- and #+ contracts
|
12
|
+
- Ensure #add and #subtract return `self`
|
13
|
+
- Make #inc(seconds, direction) public
|
14
|
+
- Implement EoTime#utc?
|
15
|
+
|
16
|
+
|
5
17
|
## et-orbi 1.0.4 released 2017-05-10
|
6
18
|
|
7
19
|
- Survive older versions of TZInfo with poor `<=>` impl, gh-1
|
data/README.md
CHANGED
@@ -19,6 +19,9 @@ EtOrbi.parse('2017-12-13 13:00:00 America/Jamaica')
|
|
19
19
|
EtOrbi.make_time(Time.now)
|
20
20
|
# => #<EtOrbi::EoTime:0x007f94d91 ...>
|
21
21
|
|
22
|
+
EtOrbi.make_time(2017, 1, 31, 12, 'Europe/Moscow').to_debug_s
|
23
|
+
# => 'ot 2017-01-31 12:00:00 +03:00 dst:false'
|
24
|
+
|
22
25
|
EtOrbi::EoTime.new(0, 'UTC').to_s
|
23
26
|
# => "1970-01-01 00:00:00 +0000"
|
24
27
|
EtOrbi::EoTime.new(0, 'Europe/Moscow').to_s
|
data/lib/et-orbi.rb
CHANGED
@@ -7,137 +7,178 @@ require 'tzinfo'
|
|
7
7
|
|
8
8
|
module EtOrbi
|
9
9
|
|
10
|
-
VERSION = '1.0.
|
10
|
+
VERSION = '1.0.5'
|
11
11
|
|
12
12
|
#
|
13
13
|
# module methods
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
EoTime.new(Time.now.to_f, zone)
|
18
|
-
end
|
15
|
+
class << self
|
19
16
|
|
20
|
-
|
17
|
+
def now(zone=nil)
|
21
18
|
|
22
|
-
|
23
|
-
return EoTime.new(t, nil)
|
19
|
+
EoTime.new(Time.now.to_f, zone)
|
24
20
|
end
|
25
21
|
|
26
|
-
|
27
|
-
#rold = RUBY_VERSION < '2.0.0'
|
22
|
+
def parse(str, opts={})
|
28
23
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
rescue
|
33
|
-
fail ArgumentError, "no time information in #{str.inspect}"
|
34
|
-
end #if rold
|
35
|
-
#
|
36
|
-
# is necessary since Time.parse('xxx') in Ruby < 1.9 yields `now`
|
24
|
+
if defined?(::Chronic) && t = ::Chronic.parse(str, opts)
|
25
|
+
return EoTime.new(t, nil)
|
26
|
+
end
|
37
27
|
|
38
|
-
|
28
|
+
#rold = RUBY_VERSION < '1.9.0'
|
29
|
+
#rold = RUBY_VERSION < '2.0.0'
|
30
|
+
begin
|
31
|
+
DateTime.parse(str)
|
32
|
+
rescue
|
33
|
+
fail ArgumentError, "no time information in #{str.inspect}"
|
34
|
+
end #if rold
|
35
|
+
#
|
36
|
+
# is necessary since Time.parse('xxx') in Ruby < 1.9 yields `now`
|
39
37
|
|
40
|
-
|
38
|
+
str_zone = get_tzone(list_iso8601_zones(str).last)
|
41
39
|
|
42
|
-
|
40
|
+
zone =
|
41
|
+
opts[:zone] ||
|
42
|
+
str_zone ||
|
43
|
+
find_olson_zone(str) ||
|
44
|
+
local_tzone
|
43
45
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
46
|
+
str = str.sub(zone.name, '') unless zone.name.match(/\A[-+]/)
|
47
|
+
#
|
48
|
+
# for 'Sun Nov 18 16:01:00 Asia/Singapore 2012',
|
49
|
+
# although where does rufus-scheduler have it from?
|
48
50
|
|
49
|
-
|
51
|
+
local = Time.parse(str)
|
50
52
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
53
|
+
secs =
|
54
|
+
if str_zone
|
55
|
+
local.to_f
|
56
|
+
else
|
57
|
+
zone.period_for_local(local).to_utc(local).to_f
|
58
|
+
end
|
57
59
|
|
58
|
-
|
59
|
-
|
60
|
+
EoTime.new(secs, zone)
|
61
|
+
end
|
62
|
+
|
63
|
+
def make_time(*a)
|
60
64
|
|
61
|
-
|
65
|
+
#p a
|
66
|
+
zone = a.length > 1 ? get_tzone(a.last) : nil
|
67
|
+
a.pop if zone
|
68
|
+
#p [ :mt, zone ]
|
69
|
+
|
70
|
+
o = a.length > 1 ? a : a.first
|
71
|
+
#p o
|
62
72
|
|
63
|
-
ot =
|
64
73
|
case o
|
65
|
-
when Time
|
66
|
-
|
67
|
-
|
68
|
-
when
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
when String
|
74
|
-
#Rufus::Scheduler.parse_in(o, :no_error => true) || self.parse(o)
|
75
|
-
parse(o)
|
76
|
-
else
|
77
|
-
o
|
74
|
+
when Time then make_from_time(o, zone)
|
75
|
+
when Date then make_from_date(o, zone)
|
76
|
+
when Array then make_from_array(o, zone)
|
77
|
+
when String then make_from_string(o, zone)
|
78
|
+
when Numeric then make_from_numeric(o, zone)
|
79
|
+
when ::EtOrbi::EoTime then make_from_eotime(o, zone)
|
80
|
+
else fail ArgumentError.new(
|
81
|
+
"cannot turn #{o.inspect} to a ::EtOrbi::EoTime instance")
|
78
82
|
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def make_from_time(t, zone)
|
86
|
+
|
87
|
+
z =
|
88
|
+
zone ||
|
89
|
+
get_tzone(t.zone) ||
|
90
|
+
(
|
91
|
+
local_tzone.period_for_local(t).abbreviation.to_s == t.zone &&
|
92
|
+
local_tzone
|
93
|
+
) ||
|
94
|
+
t.zone
|
95
|
+
|
96
|
+
EoTime.new(t.to_f, z)
|
97
|
+
end
|
79
98
|
|
80
|
-
|
99
|
+
def make_from_date(d, zone)
|
81
100
|
|
82
|
-
|
83
|
-
|
84
|
-
|
101
|
+
make_from_time(
|
102
|
+
d.respond_to?(:to_time) ?
|
103
|
+
d.to_time :
|
104
|
+
Time.parse(d.strftime('%Y-%m-%d %H:%M:%S')),
|
105
|
+
zone)
|
106
|
+
end
|
85
107
|
|
86
|
-
|
87
|
-
end
|
108
|
+
def make_from_array(a, zone)
|
88
109
|
|
89
|
-
|
110
|
+
t = Time.utc(*a)
|
111
|
+
s = t.strftime("%Y-%m-%d %H:%M:%S.#{'%06d' % t.usec}")
|
90
112
|
|
91
|
-
|
92
|
-
|
93
|
-
return local_tzone if o == :local
|
94
|
-
return ::TZInfo::Timezone.get('Zulu') if o == 'Z'
|
113
|
+
make_from_string(s, zone)
|
114
|
+
end
|
95
115
|
|
96
|
-
|
116
|
+
def make_from_string(s, zone)
|
97
117
|
|
98
|
-
|
118
|
+
parse(s, zone: zone)
|
119
|
+
end
|
99
120
|
|
100
|
-
(
|
101
|
-
get_offset_tzone(o) ||
|
102
|
-
(::TZInfo::Timezone.get(o) rescue nil)
|
103
|
-
end
|
121
|
+
def make_from_numeric(f, zone)
|
104
122
|
|
105
|
-
|
123
|
+
EoTime.new(Time.now.to_f + f, zone)
|
124
|
+
end
|
106
125
|
|
107
|
-
|
108
|
-
if @local_tzone_loaded_at && (Time.now > @local_tzone_loaded_at + 1800)
|
109
|
-
@local_tzone = nil \
|
110
|
-
if @local_tzone_tz != ENV['TZ']
|
126
|
+
def make_from_eotime(eot, zone)
|
111
127
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
@local_tzone_loaded_at = Time.now
|
116
|
-
determine_local_tzone
|
117
|
-
end
|
118
|
-
end
|
128
|
+
return eot if zone == nil || zone == eot.zone
|
129
|
+
EoTime.new(eot.to_f, zone)
|
130
|
+
end
|
119
131
|
|
120
|
-
|
121
|
-
|
122
|
-
etos = Proc.new { |k, v| "#{k}:#{v.inspect}" }
|
123
|
-
|
124
|
-
'(' +
|
125
|
-
{
|
126
|
-
'etz' => ENV['TZ'],
|
127
|
-
'tnz' => Time.now.zone,
|
128
|
-
'tzid' => defined?(TZInfo::Data),
|
129
|
-
'rv' => RUBY_VERSION,
|
130
|
-
'rp' => RUBY_PLATFORM,
|
131
|
-
'eov' => EtOrbi::VERSION,
|
132
|
-
'rorv' => (Rails::VERSION::STRING rescue nil),
|
133
|
-
'astz' => Time.respond_to?(:zone) ? Time.zone.name : nil,
|
134
|
-
# Active Support Time.zone
|
135
|
-
}.collect(&etos).join(',') + ',' +
|
136
|
-
gather_tzs.collect(&etos).join(',') +
|
137
|
-
')'
|
138
|
-
end
|
132
|
+
def get_tzone(o)
|
139
133
|
|
140
|
-
|
134
|
+
return o if o.is_a?(::TZInfo::Timezone)
|
135
|
+
return nil if o == nil
|
136
|
+
return local_tzone if o == :local
|
137
|
+
return ::TZInfo::Timezone.get('Zulu') if o == 'Z'
|
138
|
+
|
139
|
+
o = to_offset(o) if o.is_a?(Numeric)
|
140
|
+
|
141
|
+
return nil unless o.is_a?(String)
|
142
|
+
|
143
|
+
(@custom_tz_cache ||= {})[o] ||
|
144
|
+
get_offset_tzone(o) ||
|
145
|
+
(::TZInfo::Timezone.get(o) rescue nil)
|
146
|
+
end
|
147
|
+
|
148
|
+
def local_tzone
|
149
|
+
|
150
|
+
@local_tzone = nil \
|
151
|
+
if @local_tzone_loaded_at && (Time.now > @local_tzone_loaded_at + 1800)
|
152
|
+
@local_tzone = nil \
|
153
|
+
if @local_tzone_tz != ENV['TZ']
|
154
|
+
|
155
|
+
@local_tzone ||=
|
156
|
+
begin
|
157
|
+
@local_tzone_tz = ENV['TZ']
|
158
|
+
@local_tzone_loaded_at = Time.now
|
159
|
+
determine_local_tzone
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def platform_info
|
164
|
+
|
165
|
+
etos = Proc.new { |k, v| "#{k}:#{v.inspect}" }
|
166
|
+
|
167
|
+
'(' +
|
168
|
+
{
|
169
|
+
'etz' => ENV['TZ'],
|
170
|
+
'tnz' => Time.now.zone,
|
171
|
+
'tzid' => defined?(TZInfo::Data),
|
172
|
+
'rv' => RUBY_VERSION,
|
173
|
+
'rp' => RUBY_PLATFORM,
|
174
|
+
'eov' => EtOrbi::VERSION,
|
175
|
+
'rorv' => (Rails::VERSION::STRING rescue nil),
|
176
|
+
'astz' => Time.respond_to?(:zone) ? Time.zone.name : nil,
|
177
|
+
# Active Support Time.zone
|
178
|
+
}.collect(&etos).join(',') + ',' +
|
179
|
+
gather_tzs.collect(&etos).join(',') +
|
180
|
+
')'
|
181
|
+
end
|
141
182
|
|
142
183
|
alias make make_time
|
143
184
|
end
|
@@ -150,34 +191,37 @@ module EtOrbi
|
|
150
191
|
#
|
151
192
|
# class methods
|
152
193
|
|
153
|
-
|
194
|
+
class << self
|
154
195
|
|
155
|
-
|
156
|
-
end
|
196
|
+
def now(zone=nil)
|
157
197
|
|
158
|
-
|
198
|
+
EtOrbi.now(zone)
|
199
|
+
end
|
159
200
|
|
160
|
-
|
161
|
-
|
201
|
+
def parse(str, opts={})
|
202
|
+
|
203
|
+
EtOrbi.parse(str, opts)
|
204
|
+
end
|
162
205
|
|
163
|
-
|
206
|
+
def get_tzone(o)
|
164
207
|
|
165
|
-
|
166
|
-
|
208
|
+
EtOrbi.get_tzone(o)
|
209
|
+
end
|
167
210
|
|
168
|
-
|
211
|
+
def local_tzone
|
169
212
|
|
170
|
-
|
171
|
-
|
213
|
+
EtOrbi.local_tzone
|
214
|
+
end
|
172
215
|
|
173
|
-
|
216
|
+
def platform_info
|
174
217
|
|
175
|
-
|
176
|
-
|
218
|
+
EtOrbi.platform_info
|
219
|
+
end
|
177
220
|
|
178
|
-
|
221
|
+
def make(o)
|
179
222
|
|
180
|
-
|
223
|
+
EtOrbi.make_time(o)
|
224
|
+
end
|
181
225
|
end
|
182
226
|
|
183
227
|
#
|
@@ -220,6 +264,15 @@ module EtOrbi
|
|
220
264
|
Time.utc(1970, 1, 1) + @seconds
|
221
265
|
end
|
222
266
|
|
267
|
+
def utc?
|
268
|
+
|
269
|
+
%w[ zulu utc gmt ].include?(@zone.canonical_identifier.downcase)
|
270
|
+
|
271
|
+
#t = Time.now
|
272
|
+
#@zone.period_for_local(t).utc_offset == 0 &&
|
273
|
+
#@zone.period_for_local(t + 183 * 24 * 3600).utc_offset == 0
|
274
|
+
end
|
275
|
+
|
223
276
|
alias getutc utc
|
224
277
|
alias getgm utc
|
225
278
|
|
@@ -297,8 +350,8 @@ module EtOrbi
|
|
297
350
|
def <=(o); @seconds <= _to_f(o); end
|
298
351
|
def <=>(o); @seconds <=> _to_f(o); end
|
299
352
|
|
300
|
-
def add(t); @time = nil; @seconds += t.to_f; end
|
301
|
-
def subtract(t); @time = nil; @seconds -= t.to_f; end
|
353
|
+
def add(t); @time = nil; @seconds += t.to_f; self; end
|
354
|
+
def subtract(t); @time = nil; @seconds -= t.to_f; self; end
|
302
355
|
|
303
356
|
def +(t); inc(t, 1); end
|
304
357
|
def -(t); inc(t, -1); end
|
@@ -354,8 +407,47 @@ module EtOrbi
|
|
354
407
|
strftime("%H:%M:%S.#{'%06d' % usec}")
|
355
408
|
end
|
356
409
|
|
410
|
+
def inc(t, dir=1)
|
411
|
+
|
412
|
+
case t
|
413
|
+
when Numeric
|
414
|
+
nt = self.dup
|
415
|
+
nt.seconds += dir * t.to_f
|
416
|
+
nt
|
417
|
+
when ::Time, ::EtOrbi::EoTime
|
418
|
+
fail ArgumentError.new(
|
419
|
+
"cannot add #{t.class} to EoTime") if dir > 0
|
420
|
+
@seconds + dir * t.to_f
|
421
|
+
else
|
422
|
+
fail ArgumentError.new(
|
423
|
+
"cannot call add or subtract #{t.class} to EoTime instance")
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
def localtime(zone=nil)
|
428
|
+
|
429
|
+
EoTime.new(self.to_f, zone)
|
430
|
+
end
|
431
|
+
|
432
|
+
def wday_in_month
|
433
|
+
|
434
|
+
[ count_weeks(-1), - count_weeks(1) ]
|
435
|
+
end
|
436
|
+
|
357
437
|
protected
|
358
438
|
|
439
|
+
def count_weeks(dir)
|
440
|
+
|
441
|
+
c = 0
|
442
|
+
t = self
|
443
|
+
until t.month != self.month
|
444
|
+
c += 1
|
445
|
+
t += dir * (7 * 24 * 3600)
|
446
|
+
end
|
447
|
+
|
448
|
+
c
|
449
|
+
end
|
450
|
+
|
359
451
|
def render_nozone_time(seconds)
|
360
452
|
|
361
453
|
t =
|
@@ -398,20 +490,6 @@ module EtOrbi
|
|
398
490
|
fmt % [ sn, hr, mn, sc ]
|
399
491
|
end
|
400
492
|
|
401
|
-
def inc(t, dir)
|
402
|
-
|
403
|
-
if t.is_a?(Numeric)
|
404
|
-
nt = self.dup
|
405
|
-
nt.seconds += dir * t.to_f
|
406
|
-
nt
|
407
|
-
elsif t.respond_to?(:to_f)
|
408
|
-
@seconds + dir * t.to_f
|
409
|
-
else
|
410
|
-
fail ArgumentError.new(
|
411
|
-
"cannot call EoTime #- or #+ with arg of class #{t.class}")
|
412
|
-
end
|
413
|
-
end
|
414
|
-
|
415
493
|
def _to_f(o)
|
416
494
|
|
417
495
|
fail ArgumentError(
|
@@ -422,182 +500,183 @@ module EtOrbi
|
|
422
500
|
end
|
423
501
|
end
|
424
502
|
|
425
|
-
|
426
|
-
# not so public module methods
|
427
|
-
|
428
|
-
def self.time_to_eo_time(t)
|
429
|
-
|
430
|
-
z =
|
431
|
-
get_tzone(t.zone) ||
|
432
|
-
(
|
433
|
-
local_tzone.period_for_local(t).abbreviation.to_s == t.zone &&
|
434
|
-
local_tzone
|
435
|
-
) ||
|
436
|
-
t.zone
|
503
|
+
class << self
|
437
504
|
|
438
|
-
|
439
|
-
|
505
|
+
#
|
506
|
+
# extra public methods
|
440
507
|
|
441
|
-
|
508
|
+
# https://en.wikipedia.org/wiki/ISO_8601
|
509
|
+
# Postel's law applies
|
510
|
+
#
|
511
|
+
def list_iso8601_zones(s)
|
512
|
+
|
513
|
+
s.scan(
|
514
|
+
%r{
|
515
|
+
(?<=:\d\d)
|
516
|
+
\s*
|
517
|
+
(?:
|
518
|
+
[-+]
|
519
|
+
(?:[0-1][0-9]|2[0-4])
|
520
|
+
(?:(?::)?(?:[0-5][0-9]|60))?
|
521
|
+
(?![-+])
|
522
|
+
|
|
523
|
+
Z
|
524
|
+
)
|
525
|
+
}x
|
526
|
+
).collect(&:strip)
|
527
|
+
end
|
442
528
|
|
443
|
-
|
444
|
-
sn = i < 0 ? '-' : '+'; i = i.abs
|
445
|
-
hr = i / 3600; mn = i % 3600; sc = i % 60
|
446
|
-
(sc > 0 ? "%s%02d:%02d:%02d" : "%s%02d:%02d") % [ sn, hr, mn, sc ]
|
447
|
-
end
|
529
|
+
def list_olson_zones(s)
|
448
530
|
|
449
|
-
|
531
|
+
s.scan(
|
532
|
+
%r{
|
533
|
+
(?<=\s|\A)
|
534
|
+
(?:[A-Za-z][A-Za-z0-9+_-]+)
|
535
|
+
(?:\/(?:[A-Za-z][A-Za-z0-9+_-]+)){0,2}
|
536
|
+
}x)
|
537
|
+
end
|
450
538
|
|
451
|
-
|
539
|
+
def find_olson_zone(str)
|
452
540
|
|
453
|
-
|
454
|
-
|
541
|
+
list_olson_zones(str).each { |s| z = get_tzone(s); return z if z }
|
542
|
+
nil
|
543
|
+
end
|
455
544
|
|
456
|
-
|
457
|
-
mn = m[2].to_i
|
545
|
+
def determine_local_tzone
|
458
546
|
|
459
|
-
|
460
|
-
hr = nil if mn > 59
|
461
|
-
mn = -mn if hr && hr < 0
|
547
|
+
etz = ENV['TZ']
|
462
548
|
|
463
|
-
|
464
|
-
|
465
|
-
begin
|
466
|
-
tzi = TZInfo::TransitionDataTimezoneInfo.new(str)
|
467
|
-
tzi.offset(str, hr * 3600 + mn * 60, 0, str)
|
468
|
-
tzi.create_timezone
|
469
|
-
end
|
470
|
-
) if hr
|
549
|
+
tz = ::TZInfo::Timezone.get(etz) rescue nil
|
550
|
+
return tz if tz
|
471
551
|
|
472
|
-
|
473
|
-
|
552
|
+
tz = Time.zone.tzinfo \
|
553
|
+
if Time.respond_to?(:zone) && Time.zone.respond_to?(:tzinfo)
|
554
|
+
return tz if tz
|
474
555
|
|
475
|
-
|
556
|
+
tzs = determine_local_tzones
|
476
557
|
|
477
|
-
|
558
|
+
(etz && tzs.find { |z| z.name == etz }) || tzs.first
|
559
|
+
end
|
478
560
|
|
479
|
-
|
480
|
-
|
561
|
+
#
|
562
|
+
# protected module methods
|
481
563
|
|
482
|
-
|
483
|
-
if Time.respond_to?(:zone) && Time.zone.respond_to?(:tzinfo)
|
484
|
-
return tz if tz
|
564
|
+
protected
|
485
565
|
|
486
|
-
|
566
|
+
def to_offset(n)
|
487
567
|
|
488
|
-
|
489
|
-
|
568
|
+
i = n.to_i
|
569
|
+
sn = i < 0 ? '-' : '+'; i = i.abs
|
570
|
+
hr = i / 3600; mn = i % 3600; sc = i % 60
|
571
|
+
(sc > 0 ? "%s%02d:%02d:%02d" : "%s%02d:%02d") % [ sn, hr, mn, sc ]
|
572
|
+
end
|
490
573
|
|
491
|
-
|
574
|
+
def get_offset_tzone(str)
|
492
575
|
|
493
|
-
|
494
|
-
.collect { |i| (Time.now + i * 30 * 24 * 3600).zone }
|
495
|
-
.uniq
|
496
|
-
.sort
|
576
|
+
# custom timezones, no DST, just an offset, like "+08:00" or "-01:30"
|
497
577
|
|
498
|
-
|
499
|
-
|
578
|
+
m = str.match(/\A([+-][0-1][0-9]):?([0-5][0-9])?\z/)
|
579
|
+
return nil unless m
|
500
580
|
|
501
|
-
|
502
|
-
|
581
|
+
hr = m[1].to_i
|
582
|
+
mn = m[2].to_i
|
503
583
|
|
504
|
-
|
584
|
+
hr = nil if hr.abs > 11
|
585
|
+
hr = nil if mn > 59
|
586
|
+
mn = -mn if hr && hr < 0
|
505
587
|
|
506
|
-
|
507
|
-
[
|
508
|
-
|
509
|
-
|
510
|
-
|
588
|
+
return (
|
589
|
+
@custom_tz_cache[str] =
|
590
|
+
begin
|
591
|
+
tzi = TZInfo::TransitionDataTimezoneInfo.new(str)
|
592
|
+
tzi.offset(str, hr * 3600 + mn * 60, 0, str)
|
593
|
+
tzi.create_timezone
|
594
|
+
end
|
595
|
+
) if hr
|
511
596
|
|
512
|
-
|
597
|
+
nil
|
513
598
|
end
|
514
|
-
end
|
515
599
|
|
516
|
-
|
517
|
-
# Postel's law applies
|
518
|
-
#
|
519
|
-
def self.list_iso8601_zones(s)
|
520
|
-
|
521
|
-
s.scan(
|
522
|
-
%r{
|
523
|
-
(?<=:\d\d)
|
524
|
-
\s*
|
525
|
-
(?:
|
526
|
-
[-+]
|
527
|
-
(?:[0-1][0-9]|2[0-4])
|
528
|
-
(?:(?::)?(?:[0-5][0-9]|60))?
|
529
|
-
(?![-+])
|
530
|
-
|
|
531
|
-
Z
|
532
|
-
)
|
533
|
-
}x
|
534
|
-
).collect(&:strip)
|
535
|
-
end
|
600
|
+
def determine_local_tzones
|
536
601
|
|
537
|
-
|
602
|
+
tabbs = (-6..5)
|
603
|
+
.collect { |i| (Time.now + i * 30 * 24 * 3600).zone }
|
604
|
+
.uniq
|
605
|
+
.sort
|
538
606
|
|
539
|
-
|
540
|
-
|
541
|
-
(?<=\s|\A)
|
542
|
-
(?:[A-Za-z][A-Za-z0-9+_-]+)
|
543
|
-
(?:\/(?:[A-Za-z][A-Za-z0-9+_-]+)){0,2}
|
544
|
-
}x)
|
545
|
-
end
|
607
|
+
t = Time.now
|
608
|
+
tu = t.dup.utc # /!\ dup is necessary, #utc modifies its target
|
546
609
|
|
547
|
-
|
548
|
-
|
549
|
-
# current_timezone = ENV['TZ']
|
550
|
-
# ENV['TZ'] = @zone
|
551
|
-
#
|
552
|
-
# block.call
|
553
|
-
#
|
554
|
-
#ensure
|
555
|
-
#
|
556
|
-
# ENV['TZ'] = current_timezone
|
557
|
-
#end
|
558
|
-
#
|
559
|
-
# kept around as a (thread-unsafe) relic
|
610
|
+
twin = Time.utc(t.year, 1, 1) # winter
|
611
|
+
tsum = Time.utc(t.year, 7, 1) # summer
|
560
612
|
|
561
|
-
|
562
|
-
# system tz determination
|
613
|
+
::TZInfo::Timezone.all.select do |tz|
|
563
614
|
|
564
|
-
|
615
|
+
pabbs =
|
616
|
+
[
|
617
|
+
tz.period_for_utc(twin).abbreviation.to_s,
|
618
|
+
tz.period_for_utc(tsum).abbreviation.to_s
|
619
|
+
].uniq.sort
|
565
620
|
|
566
|
-
|
621
|
+
pabbs == tabbs
|
622
|
+
end
|
623
|
+
end
|
567
624
|
|
568
|
-
|
569
|
-
|
625
|
+
#
|
626
|
+
# system tz determination
|
570
627
|
|
571
|
-
|
628
|
+
def debian_tz
|
572
629
|
|
573
|
-
|
630
|
+
path = '/etc/timezone'
|
574
631
|
|
575
|
-
|
576
|
-
|
577
|
-
if m = f.readline.match(/ZONE="([^"]+)"/); return m[1]; end
|
578
|
-
end
|
579
|
-
end if File.exist?(path)
|
632
|
+
File.exist?(path) ? File.read(path).strip : nil
|
633
|
+
rescue; nil; end
|
580
634
|
|
581
|
-
|
582
|
-
rescue; nil; end
|
635
|
+
def centos_tz
|
583
636
|
|
584
|
-
|
637
|
+
path = '/etc/sysconfig/clock'
|
585
638
|
|
586
|
-
|
639
|
+
File.open(path, 'rb') do |f|
|
640
|
+
until f.eof?
|
641
|
+
if m = f.readline.match(/ZONE="([^"]+)"/); return m[1]; end
|
642
|
+
end
|
643
|
+
end if File.exist?(path)
|
587
644
|
|
588
|
-
File.symlink?(path) ?
|
589
|
-
File.readlink(path).split('/')[4..-1].join('/') :
|
590
645
|
nil
|
591
|
-
|
646
|
+
rescue; nil; end
|
592
647
|
|
593
|
-
|
648
|
+
def osx_tz
|
649
|
+
|
650
|
+
path = '/etc/localtime'
|
651
|
+
|
652
|
+
File.symlink?(path) ?
|
653
|
+
File.readlink(path).split('/')[4..-1].join('/') :
|
654
|
+
nil
|
655
|
+
rescue; nil; end
|
656
|
+
|
657
|
+
# def find_tz
|
594
658
|
#
|
595
|
-
#
|
596
|
-
#
|
659
|
+
# debian_tz || centos_tz || osx_tz
|
660
|
+
# end
|
597
661
|
|
598
|
-
|
662
|
+
def gather_tzs
|
599
663
|
|
600
|
-
|
664
|
+
{ :debian => debian_tz, :centos => centos_tz, :osx => osx_tz }
|
665
|
+
end
|
601
666
|
end
|
667
|
+
|
668
|
+
#def in_zone(&block)
|
669
|
+
#
|
670
|
+
# current_timezone = ENV['TZ']
|
671
|
+
# ENV['TZ'] = @zone
|
672
|
+
#
|
673
|
+
# block.call
|
674
|
+
#
|
675
|
+
#ensure
|
676
|
+
#
|
677
|
+
# ENV['TZ'] = current_timezone
|
678
|
+
#end
|
679
|
+
#
|
680
|
+
# kept around as a (thread-unsafe) relic
|
602
681
|
end
|
603
682
|
|
metadata
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: et-orbi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Mettraux
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tzinfo
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '3.4'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '3.4'
|
41
41
|
description: Time zones for fugit and rufus-scheduler. Urbi et Orbi.
|
@@ -45,15 +45,15 @@ executables: []
|
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
|
+
- CHANGELOG.md
|
49
|
+
- CREDITS.md
|
50
|
+
- LICENSE.txt
|
48
51
|
- Makefile
|
52
|
+
- README.md
|
53
|
+
- et-orbi.gemspec
|
49
54
|
- lib/et-orbi.rb
|
50
55
|
- lib/et_orbi.rb
|
51
56
|
- lib/etorbi.rb
|
52
|
-
- et-orbi.gemspec
|
53
|
-
- LICENSE.txt
|
54
|
-
- CHANGELOG.md
|
55
|
-
- CREDITS.md
|
56
|
-
- README.md
|
57
57
|
homepage: http://github.com/floraison/et-orbi
|
58
58
|
licenses:
|
59
59
|
- MIT
|
@@ -64,17 +64,17 @@ require_paths:
|
|
64
64
|
- lib
|
65
65
|
required_ruby_version: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '0'
|
70
70
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
|
-
- -
|
72
|
+
- - ">="
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '0'
|
75
75
|
requirements: []
|
76
76
|
rubyforge_project:
|
77
|
-
rubygems_version: 2.
|
77
|
+
rubygems_version: 2.5.2
|
78
78
|
signing_key:
|
79
79
|
specification_version: 4
|
80
80
|
summary: time with zones
|