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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 63be401cf92b7f62cbb8c778d9ec512c89cd7fc1
4
- data.tar.gz: 9e9668a7250fe51ead41650067e04e7c4a29d505
3
+ metadata.gz: 65b5afb2d0d4f7f1865b20129ff6896d735452b9
4
+ data.tar.gz: 57b48b7cd3835dce5bdd50628d704928c34c27e2
5
5
  SHA512:
6
- metadata.gz: ec5bf95f98d1a528e2411b39c7bea0a32154b6c11345cb37b0da89aabdcf2d110dccee14e045433961bf849e78b381b945279cdeb4575bcd4a4da4c3f888e1c0
7
- data.tar.gz: 33028c93d34cd0129f09f4dee8213311588f56f87c3b69495c58dae0f4de23803919b406df8538878c9ce0bb4628cf211f1c0cd27bc7c0b4acac6fb33382fcb1
6
+ metadata.gz: ed22b3055df4153c0c24be1f96b06dfa953c0638acb09d571f0df359d468b30524e4c70e9d5b013097731542b1b941603f1d8507b7689bf39a281f2d27d32318
7
+ data.tar.gz: 99a5479d314b98484d64575d5a446b33c122af030f1643c9a40fc1b80846a56f411b0ca272b58255f18b7862be8699fd61df90a7b99ee956f5fd14534d0f7e1f
@@ -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
 
@@ -4,510 +4,15 @@ require 'time'
4
4
 
5
5
  require 'tzinfo'
6
6
 
7
- require 'et-orbi/eo_time'
8
- require 'et-orbi/zone_aliases'
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.7'
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