rufus-scheduler 2.0.24 → 3.1.0

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.
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
+