rufus-scheduler 2.0.24 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/CHANGELOG.txt +76 -0
  2. data/CREDITS.txt +23 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +1439 -0
  5. data/Rakefile +1 -5
  6. data/TODO.txt +149 -55
  7. data/lib/rufus/{sc → scheduler}/cronline.rb +167 -53
  8. data/lib/rufus/scheduler/job_array.rb +92 -0
  9. data/lib/rufus/scheduler/jobs.rb +633 -0
  10. data/lib/rufus/scheduler/locks.rb +95 -0
  11. data/lib/rufus/scheduler/util.rb +306 -0
  12. data/lib/rufus/scheduler/zones.rb +174 -0
  13. data/lib/rufus/scheduler/zotime.rb +154 -0
  14. data/lib/rufus/scheduler.rb +608 -27
  15. data/rufus-scheduler.gemspec +6 -4
  16. data/spec/basics_spec.rb +54 -0
  17. data/spec/cronline_spec.rb +479 -152
  18. data/spec/error_spec.rb +139 -0
  19. data/spec/job_array_spec.rb +39 -0
  20. data/spec/job_at_spec.rb +58 -0
  21. data/spec/job_cron_spec.rb +128 -0
  22. data/spec/job_every_spec.rb +104 -0
  23. data/spec/job_in_spec.rb +20 -0
  24. data/spec/job_interval_spec.rb +68 -0
  25. data/spec/job_repeat_spec.rb +357 -0
  26. data/spec/job_spec.rb +498 -109
  27. data/spec/lock_custom_spec.rb +47 -0
  28. data/spec/lock_flock_spec.rb +47 -0
  29. data/spec/lock_lockfile_spec.rb +61 -0
  30. data/spec/lock_spec.rb +59 -0
  31. data/spec/parse_spec.rb +263 -0
  32. data/spec/schedule_at_spec.rb +158 -0
  33. data/spec/schedule_cron_spec.rb +66 -0
  34. data/spec/schedule_every_spec.rb +109 -0
  35. data/spec/schedule_in_spec.rb +80 -0
  36. data/spec/schedule_interval_spec.rb +128 -0
  37. data/spec/scheduler_spec.rb +928 -124
  38. data/spec/spec_helper.rb +126 -0
  39. data/spec/threads_spec.rb +96 -0
  40. data/spec/zotime_spec.rb +396 -0
  41. metadata +56 -33
  42. data/README.rdoc +0 -661
  43. data/lib/rufus/otime.rb +0 -3
  44. data/lib/rufus/sc/jobqueues.rb +0 -160
  45. data/lib/rufus/sc/jobs.rb +0 -471
  46. data/lib/rufus/sc/rtime.rb +0 -363
  47. data/lib/rufus/sc/scheduler.rb +0 -636
  48. data/lib/rufus/sc/version.rb +0 -32
  49. data/spec/at_in_spec.rb +0 -47
  50. data/spec/at_spec.rb +0 -125
  51. data/spec/blocking_spec.rb +0 -64
  52. data/spec/cron_spec.rb +0 -134
  53. data/spec/every_spec.rb +0 -304
  54. data/spec/exception_spec.rb +0 -113
  55. data/spec/in_spec.rb +0 -150
  56. data/spec/mutex_spec.rb +0 -159
  57. data/spec/rtime_spec.rb +0 -137
  58. data/spec/schedulable_spec.rb +0 -97
  59. data/spec/spec_base.rb +0 -87
  60. data/spec/stress_schedule_unschedule_spec.rb +0 -159
  61. data/spec/timeout_spec.rb +0 -148
  62. data/test/kjw.rb +0 -113
  63. data/test/t.rb +0 -20
@@ -0,0 +1,126 @@
1
+
2
+ #
3
+ # Specifying rufus-scheduler
4
+ #
5
+ # Wed Apr 17 06:00:59 JST 2013
6
+ #
7
+
8
+ puts "RUBY_VERSION: #{RUBY_VERSION}"
9
+ puts "RUBY_PLATFORM: #{RUBY_PLATFORM}"
10
+
11
+ Thread.abort_on_exception = true
12
+
13
+ require 'stringio'
14
+ require 'rufus-scheduler'
15
+
16
+ #
17
+ # misc helper methods
18
+
19
+ def ruby18?
20
+
21
+ !! RUBY_VERSION.match(/^1\.8\./)
22
+ end
23
+
24
+ def jruby?
25
+
26
+ !! RUBY_PLATFORM.match(/java/)
27
+ end
28
+
29
+ def local(*args)
30
+
31
+ Time.local(*args)
32
+ end
33
+ alias lo local
34
+
35
+ def utc(*args)
36
+
37
+ Time.utc(*args)
38
+ end
39
+
40
+ def ltz(tz, *args)
41
+
42
+ in_zone(tz) { Time.local(*args) }
43
+ end
44
+
45
+ def ltu(tz, *args)
46
+
47
+ in_zone(tz) { Time.local(*args) }.getutc
48
+ end
49
+
50
+ def sleep_until_next_minute
51
+
52
+ min = Time.now.min
53
+ while Time.now.min == min; sleep 2; end
54
+ end
55
+
56
+ def sleep_until_next_second
57
+
58
+ sec = Time.now.sec
59
+ while Time.now.sec == sec; sleep 0.2; end
60
+ end
61
+
62
+ def in_zone(zone_name, &block)
63
+
64
+ prev_tz = ENV['TZ']
65
+ ENV['TZ'] = zone_name
66
+
67
+ block.call
68
+
69
+ ensure
70
+
71
+ ENV['TZ'] = prev_tz
72
+ end
73
+
74
+ def with_chronic(&block)
75
+
76
+ require 'chronic'
77
+
78
+ Object.const_set(:Khronic, Chronic) unless defined?(Khronic)
79
+ Object.const_set(:Chronic, Khronic) unless defined?(Chronic)
80
+
81
+ block.call
82
+
83
+ ensure
84
+
85
+ Object.send(:remove_const, :Chronic)
86
+ end
87
+
88
+ def without_chronic(&block) # for quick counter-tests ;-)
89
+
90
+ block.call
91
+ end
92
+
93
+
94
+ #
95
+ # matchers
96
+
97
+ #require 'rspec/expectations'
98
+
99
+ RSpec::Matchers.define :be_within_1s_of do |expected|
100
+
101
+ match do |actual|
102
+
103
+ if actual.respond_to?(:asctime)
104
+ (actual.to_f - expected.to_f).abs <= 1.0
105
+ else
106
+ false
107
+ end
108
+ end
109
+
110
+ failure_message do |actual|
111
+
112
+ if actual.respond_to?(:asctime)
113
+ "expected #{actual.inspect} to be within 1 second of #{expected}"
114
+ else
115
+ "expected Time instance, got a #{actual.inspect}"
116
+ end
117
+ end
118
+ end
119
+
120
+
121
+ #
122
+ # configure
123
+
124
+ #RSpec.configure do |config|
125
+ #end
126
+
@@ -0,0 +1,96 @@
1
+
2
+ #
3
+ # Specifying rufus-scheduler
4
+ #
5
+ # Thu Jul 25 05:53:51 JST 2013
6
+ #
7
+
8
+ require 'spec_helper'
9
+
10
+
11
+ describe Rufus::Scheduler do
12
+
13
+ before :each do
14
+ @scheduler = Rufus::Scheduler.new
15
+ end
16
+ after :each do
17
+ @scheduler.shutdown
18
+ end
19
+
20
+ context 'thread pool' do
21
+
22
+ it 'starts with an empty thread pool' do
23
+
24
+ expect(@scheduler.work_threads.size).to eq(0)
25
+ end
26
+
27
+ it 'does not cross the max_work_threads threshold' do
28
+
29
+ #@scheduler.min_work_threads = 2
30
+ @scheduler.max_work_threads = 5
31
+
32
+ 10.times do
33
+ @scheduler.in '0s' do
34
+ sleep 5
35
+ end
36
+ end
37
+
38
+ sleep 0.5
39
+
40
+ #@scheduler.job_threads.each do |t|
41
+ # p t.keys
42
+ # p t[:rufus_scheduler_job].class
43
+ #end
44
+
45
+ expect(@scheduler.work_threads.size).to eq(5)
46
+ end
47
+
48
+ it 'does not cross the max_work_threads threshold (overlap: false)' do
49
+
50
+ #@scheduler.min_work_threads = 2
51
+ @scheduler.max_work_threads = 5
52
+
53
+ 10.times do
54
+ @scheduler.in '0s', :overlap => false do
55
+ sleep 5
56
+ end
57
+ end
58
+
59
+ sleep 0.5
60
+
61
+ #@scheduler.job_threads.each do |t|
62
+ # p t.keys
63
+ # p t[:rufus_scheduler_job].class
64
+ #end
65
+
66
+ expect(@scheduler.work_threads.size).to eq(5)
67
+ end
68
+
69
+ it 'does not execute unscheduled jobs' do
70
+
71
+ @scheduler.max_work_threads = 1
72
+
73
+ counter = 0
74
+
75
+ job0 =
76
+ @scheduler.schedule_in '0.3s' do
77
+ counter += 1
78
+ sleep 1
79
+ end
80
+ job1 =
81
+ @scheduler.schedule_in '0.35s' do
82
+ counter += 1
83
+ sleep 1
84
+ end
85
+
86
+ sleep(0.1) while counter < 1
87
+ sleep(0.1) while @scheduler.work_queue.size < 1
88
+ job1.unschedule
89
+
90
+ sleep(2)
91
+
92
+ expect(counter).to eq(1)
93
+ end
94
+ end
95
+ end
96
+
@@ -0,0 +1,396 @@
1
+
2
+ #
3
+ # Specifying rufus-scheduler
4
+ #
5
+ # Wed Mar 11 21:17:36 JST 2015, quatre ans...
6
+ #
7
+
8
+ require 'spec_helper'
9
+
10
+
11
+ describe Rufus::Scheduler::ZoTime do
12
+
13
+ describe '.new' do
14
+
15
+ it 'accepts an integer' do
16
+
17
+ zt = Rufus::Scheduler::ZoTime.new(1234567890, 'America/Los_Angeles')
18
+
19
+ expect(zt.seconds.to_i).to eq(1234567890)
20
+ end
21
+
22
+ it 'accepts a float' do
23
+
24
+ zt = Rufus::Scheduler::ZoTime.new(1234567890.1234, 'America/Los_Angeles')
25
+
26
+ expect(zt.seconds.to_i).to eq(1234567890)
27
+ end
28
+
29
+ it 'accepts a Time instance' do
30
+
31
+ zt =
32
+ Rufus::Scheduler::ZoTime.new(
33
+ Time.utc(2007, 11, 1, 15, 25, 0),
34
+ 'America/Los_Angeles')
35
+
36
+ expect(zt.seconds.to_i).to eq(1193930700)
37
+ end
38
+ end
39
+
40
+ #it "flips burgers" do
41
+ # puts "---"
42
+ # t0 = ltz('America/New_York', 2004, 10, 31, 0, 30, 0)
43
+ # t1 = ltz('America/New_York', 2004, 10, 31, 1, 30, 0)
44
+ # p t0
45
+ # p t1
46
+ # puts "---"
47
+ # zt0 = Rufus::Scheduler::ZoTime.new(t0, 'America/New_York')
48
+ # zt1 = Rufus::Scheduler::ZoTime.new(t1, 'America/New_York')
49
+ # p zt0.time
50
+ # p zt1.time
51
+ # puts "---"
52
+ # zt0.add(3600)
53
+ # p [ zt0.time, zt0.time.zone ]
54
+ # p [ zt1.time, zt1.time.zone ]
55
+ # #puts "---"
56
+ # #zt0.add(3600)
57
+ # #zt1.add(3600)
58
+ # #p [ zt0.time, zt0.time.zone ]
59
+ # #p [ zt1.time, zt1.time.zone ]
60
+ #end
61
+
62
+ describe '#time' do
63
+
64
+ it 'returns a Time instance in with the right offset' do
65
+
66
+ zt = Rufus::Scheduler::ZoTime.new(1193898300, 'America/Los_Angeles')
67
+ t = zt.time
68
+
69
+ expect(t.strftime('%Y/%m/%d %H:%M:%S %Z')
70
+ ).to eq('2007/10/31 23:25:00 PDT')
71
+ end
72
+
73
+ # New York EST: UTC-5
74
+ # summer (dst) EDT: UTC-4
75
+
76
+ it 'chooses the non DST time when there is ambiguity' do
77
+
78
+ t = ltz('America/New_York', 2004, 10, 31, 0, 30, 0)
79
+ zt = Rufus::Scheduler::ZoTime.new(t, 'America/New_York')
80
+ zt.add(3600)
81
+ ztt = zt.time
82
+
83
+ expect(ztt.to_i).to eq(1099204200)
84
+
85
+ if ruby18?
86
+ expect(ztt.strftime('%Y/%m/%d %H:%M:%S %Z %z')
87
+ ).to eq('2004/10/31 01:30:00 EST -0500')
88
+ else
89
+ expect(ztt.strftime('%Y/%m/%d %H:%M:%S %Z %z')
90
+ ).to eq('2004/10/31 01:30:00 EST -0500')
91
+ end
92
+ end
93
+ end
94
+
95
+ describe '#utc' do
96
+
97
+ it 'returns an UTC Time instance' do
98
+
99
+ zt = Rufus::Scheduler::ZoTime.new(1193898300, 'America/Los_Angeles')
100
+ t = zt.utc
101
+
102
+ expect(t.to_i).to eq(1193898300)
103
+
104
+ if ruby18?
105
+ expect(t.strftime('%Y/%m/%d %H:%M:%S %Z %z')
106
+ ).to eq('2007/11/01 06:25:00 GMT +0000')
107
+ else
108
+ expect(t.strftime('%Y/%m/%d %H:%M:%S %Z %z')
109
+ ).to eq('2007/11/01 06:25:00 UTC +0000')
110
+ end
111
+ end
112
+ end
113
+
114
+ describe '#add' do
115
+
116
+ it 'adds seconds' do
117
+
118
+ zt = Rufus::Scheduler::ZoTime.new(1193898300, 'Europe/Paris')
119
+ zt.add(111)
120
+
121
+ expect(zt.seconds).to eq(1193898300 + 111)
122
+ end
123
+
124
+ it 'goes into DST' do
125
+
126
+ zt =
127
+ Rufus::Scheduler::ZoTime.new(
128
+ Time.gm(2015, 3, 8, 9, 59, 59),
129
+ 'America/Los_Angeles')
130
+
131
+ t0 = zt.time
132
+ zt.add(1)
133
+ t1 = zt.time
134
+
135
+ st0 = t0.strftime('%Y/%m/%d %H:%M:%S %Z') + " #{t0.isdst}"
136
+ st1 = t1.strftime('%Y/%m/%d %H:%M:%S %Z') + " #{t1.isdst}"
137
+
138
+ expect(t0.to_i).to eq(1425808799)
139
+ expect(t1.to_i).to eq(1425808800)
140
+ expect(st0).to eq('2015/03/08 01:59:59 PST false')
141
+ expect(st1).to eq('2015/03/08 03:00:00 PDT true')
142
+ end
143
+
144
+ it 'goes out of DST' do
145
+
146
+ zt =
147
+ Rufus::Scheduler::ZoTime.new(
148
+ ltz('Europe/Berlin', 2014, 10, 26, 01, 59, 59),
149
+ 'Europe/Berlin')
150
+
151
+ t0 = zt.time
152
+ zt.add(1)
153
+ t1 = zt.time
154
+ zt.add(3600)
155
+ t2 = zt.time
156
+ zt.add(1)
157
+ t3 = zt.time
158
+
159
+ st0 = t0.strftime('%Y/%m/%d %H:%M:%S %Z') + " #{t0.isdst}"
160
+ st1 = t1.strftime('%Y/%m/%d %H:%M:%S %Z') + " #{t1.isdst}"
161
+ st2 = t2.strftime('%Y/%m/%d %H:%M:%S %Z') + " #{t2.isdst}"
162
+ st3 = t3.strftime('%Y/%m/%d %H:%M:%S %Z') + " #{t3.isdst}"
163
+
164
+ expect(t0.to_i).to eq(1414281599)
165
+ expect(t1.to_i).to eq(1414285200)
166
+ expect(t2.to_i).to eq(1414285200)
167
+ expect(t3.to_i).to eq(1414285201)
168
+
169
+ expect(st0).to eq('2014/10/26 01:59:59 CEST true')
170
+ expect(st1).to eq('2014/10/26 02:00:00 CET false')
171
+ expect(st2).to eq('2014/10/26 02:00:00 CET false')
172
+ expect(st3).to eq('2014/10/26 02:00:01 CET false')
173
+
174
+ expect(t1 - t0).to eq(3601)
175
+ expect(t2 - t1).to eq(0)
176
+ expect(t3 - t2).to eq(1)
177
+ end
178
+ end
179
+
180
+ describe '#to_f' do
181
+
182
+ it 'returns the @seconds' do
183
+
184
+ zt = Rufus::Scheduler::ZoTime.new(1193898300, 'Europe/Paris')
185
+
186
+ expect(zt.to_f).to eq(1193898300)
187
+ end
188
+ end
189
+
190
+ describe '.envtzable?' do
191
+
192
+ def etza?(s); Rufus::Scheduler::ZoTime.envtzable?(s); end
193
+
194
+ it 'matches' do
195
+
196
+ expect(etza?('Asia/Tokyo')).to eq(true)
197
+ expect(etza?('America/Los_Angeles')).to eq(true)
198
+ expect(etza?('Europe/Paris')).to eq(true)
199
+ expect(etza?('UTC')).to eq(true)
200
+
201
+ expect(etza?('Japan')).to eq(true)
202
+ expect(etza?('Turkey')).to eq(true)
203
+ end
204
+
205
+ it 'does not match' do
206
+
207
+ expect(etza?('14:00')).to eq(false)
208
+ expect(etza?('14:00:14')).to eq(false)
209
+ expect(etza?('2014/12/11')).to eq(false)
210
+ expect(etza?('2014-12-11')).to eq(false)
211
+ expect(etza?('+25:00')).to eq(false)
212
+
213
+ expect(etza?('+09:00')).to eq(false)
214
+ expect(etza?('-01:30')).to eq(false)
215
+ expect(etza?('-0200')).to eq(false)
216
+
217
+ expect(etza?('Wed')).to eq(false)
218
+ expect(etza?('Sun')).to eq(false)
219
+ expect(etza?('Nov')).to eq(false)
220
+
221
+ expect(etza?('PST')).to eq(false)
222
+ expect(etza?('Z')).to eq(false)
223
+
224
+ expect(etza?('YTC')).to eq(false)
225
+ expect(etza?('Asia/Paris')).to eq(false)
226
+ expect(etza?('Nada/Nada')).to eq(false)
227
+ end
228
+
229
+ #it 'returns true for all entries in the tzinfo list' do
230
+ # File.readlines(
231
+ # File.join(File.dirname(__FILE__), '../misc/tz_all.txt')
232
+ # ).each do |tz|
233
+ # tz = tz.strip
234
+ # if tz.length > 0 && tz.match(/^[^#]/)
235
+ # p tz
236
+ # expect(llat?(tz)).to eq(true)
237
+ # end
238
+ # end
239
+ #end
240
+ end
241
+
242
+ describe '.is_timezone?' do
243
+
244
+ def is_timezone?(o); Rufus::Scheduler::ZoTime.is_timezone?(o); end
245
+
246
+ it 'returns true when passed a string describing a timezone' do
247
+
248
+ expect(is_timezone?('Asia/Tokyo')).to eq(true)
249
+ expect(is_timezone?('Europe/Paris')).to eq(true)
250
+ expect(is_timezone?('UTC')).to eq(true)
251
+ expect(is_timezone?('GMT')).to eq(true)
252
+ expect(is_timezone?('Z')).to eq(true)
253
+ expect(is_timezone?('Zulu')).to eq(true)
254
+ expect(is_timezone?('PST')).to eq(true)
255
+ expect(is_timezone?('+09:00')).to eq(true)
256
+ expect(is_timezone?('-01:30')).to eq(true)
257
+ expect(is_timezone?('Japan')).to eq(true)
258
+ expect(is_timezone?('Turkey')).to eq(true)
259
+ end
260
+
261
+ it 'returns false when it cannot make sense of the timezone' do
262
+
263
+ expect(is_timezone?('Asia/Paris')).to eq(false)
264
+ #expect(is_timezone?('YTC')).to eq(false)
265
+ expect(is_timezone?('Nada/Nada')).to eq(false)
266
+ expect(is_timezone?('7')).to eq(false)
267
+ expect(is_timezone?('06')).to eq(false)
268
+ expect(is_timezone?('sun#3')).to eq(false)
269
+ end
270
+
271
+ #it 'returns true for all entries in the tzinfo list' do
272
+ # File.readlines(
273
+ # File.join(File.dirname(__FILE__), '../misc/tz_all.txt')
274
+ # ).each do |tz|
275
+ # tz = tz.strip
276
+ # if tz.length > 0 && tz.match(/^[^#]/)
277
+ # #p tz
278
+ # expect(is_timezone?(tz)).to eq(true)
279
+ # end
280
+ # end
281
+ #end
282
+ end
283
+
284
+ describe '.parse' do
285
+
286
+ it 'parses a time string without a timezone' do
287
+
288
+ zt =
289
+ in_zone('Europe/Moscow') {
290
+ Rufus::Scheduler::ZoTime.parse('2015/03/08 01:59:59')
291
+ }
292
+
293
+ t = zt.time
294
+ u = zt.utc
295
+
296
+ expect(t.to_i).to eq(1425769199)
297
+ expect(u.to_i).to eq(1425769199)
298
+
299
+ expect(t.strftime('%Y/%m/%d %H:%M:%S %Z %z') + " #{t.isdst}"
300
+ ).to eq('2015/03/08 01:59:59 MSK +0300 false')
301
+
302
+ if ruby18?
303
+ expect(u.strftime('%Y/%m/%d %H:%M:%S %Z %z') + " #{u.isdst}"
304
+ ).to eq('2015/03/07 22:59:59 GMT +0000 false')
305
+ else
306
+ expect(u.strftime('%Y/%m/%d %H:%M:%S %Z %z') + " #{u.isdst}"
307
+ ).to eq('2015/03/07 22:59:59 UTC +0000 false')
308
+ end
309
+ end
310
+
311
+ it 'parses a time string with a full name timezone' do
312
+
313
+ zt =
314
+ Rufus::Scheduler::ZoTime.parse(
315
+ '2015/03/08 01:59:59 America/Los_Angeles')
316
+
317
+ t = zt.time
318
+ u = zt.utc
319
+
320
+ expect(t.to_i).to eq(1425808799)
321
+ expect(u.to_i).to eq(1425808799)
322
+
323
+ expect(t.strftime('%Y/%m/%d %H:%M:%S %Z %z') + " #{t.isdst}"
324
+ ).to eq('2015/03/08 01:59:59 PST -0800 false')
325
+
326
+ if ruby18?
327
+ expect(u.strftime('%Y/%m/%d %H:%M:%S %Z %z') + " #{u.isdst}"
328
+ ).to eq('2015/03/08 09:59:59 GMT +0000 false')
329
+ else
330
+ expect(u.strftime('%Y/%m/%d %H:%M:%S %Z %z') + " #{u.isdst}"
331
+ ).to eq('2015/03/08 09:59:59 UTC +0000 false')
332
+ end
333
+ end
334
+
335
+ it 'parses a time string with a delta timezone' do
336
+
337
+ zt =
338
+ in_zone('Europe/Berlin') {
339
+ Rufus::Scheduler::ZoTime.parse('2015-12-13 12:30 -0200')
340
+ }
341
+
342
+ t = zt.time
343
+ u = zt.utc
344
+
345
+ expect(t.to_i).to eq(1450017000)
346
+ expect(u.to_i).to eq(1450017000)
347
+
348
+ expect(t.strftime('%Y/%m/%d %H:%M:%S %Z %z') + " #{t.isdst}"
349
+ ).to eq('2015/12/13 15:30:00 CET +0100 false')
350
+
351
+ if ruby18?
352
+ expect(u.strftime('%Y/%m/%d %H:%M:%S %Z %z') + " #{u.isdst}"
353
+ ).to eq('2015/12/13 14:30:00 GMT +0000 false')
354
+ else
355
+ expect(u.strftime('%Y/%m/%d %H:%M:%S %Z %z') + " #{u.isdst}"
356
+ ).to eq('2015/12/13 14:30:00 UTC +0000 false')
357
+ end
358
+ end
359
+
360
+ it 'parses a time string with a delta (:) timezone' do
361
+
362
+ zt =
363
+ in_zone('Europe/Berlin') {
364
+ Rufus::Scheduler::ZoTime.parse('2015-12-13 12:30 -02:00')
365
+ }
366
+
367
+ t = zt.time
368
+ u = zt.utc
369
+
370
+ expect(t.to_i).to eq(1450017000)
371
+ expect(u.to_i).to eq(1450017000)
372
+
373
+ expect(t.strftime('%Y/%m/%d %H:%M:%S %Z %z') + " #{t.isdst}"
374
+ ).to eq('2015/12/13 15:30:00 CET +0100 false')
375
+
376
+ if ruby18?
377
+ expect(u.strftime('%Y/%m/%d %H:%M:%S %Z %z') + " #{u.isdst}"
378
+ ).to eq('2015/12/13 14:30:00 GMT +0000 false')
379
+ else
380
+ expect(u.strftime('%Y/%m/%d %H:%M:%S %Z %z') + " #{u.isdst}"
381
+ ).to eq('2015/12/13 14:30:00 UTC +0000 false')
382
+ end
383
+ end
384
+
385
+ it 'takes the local TZ when it does not know the timezone' do
386
+
387
+ in_zone 'Europe/Moscow' do
388
+
389
+ zt = Rufus::Scheduler::ZoTime.parse('2015/03/08 01:59:59 Nada/Nada')
390
+
391
+ expect(zt.time.zone).to eq('MSK')
392
+ end
393
+ end
394
+ end
395
+ end
396
+