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,306 @@
1
+ #--
2
+ # Copyright (c) 2006-2015, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ module Rufus
27
+
28
+ class Scheduler
29
+
30
+ #--
31
+ # time and string methods
32
+ #++
33
+
34
+ def self.parse(o, opts={})
35
+
36
+ opts[:no_error] = true
37
+
38
+ parse_cron(o, opts) ||
39
+ parse_in(o, opts) || # covers 'every' schedule strings
40
+ parse_at(o, opts) ||
41
+ raise(ArgumentError.new("couldn't parse \"#{o}\""))
42
+ end
43
+
44
+ def self.parse_in(o, opts={})
45
+
46
+ o.is_a?(String) ? parse_duration(o, opts) : o
47
+ end
48
+
49
+ def self.parse_at(o, opts={})
50
+
51
+ Rufus::Scheduler::ZoTime.parse(o, opts).time
52
+
53
+ rescue StandardError => se
54
+
55
+ return nil if opts[:no_error]
56
+ raise se
57
+ end
58
+
59
+ def self.parse_cron(o, opts)
60
+
61
+ CronLine.new(o)
62
+
63
+ rescue ArgumentError => ae
64
+
65
+ return nil if opts[:no_error]
66
+ raise ae
67
+ end
68
+
69
+ def self.parse_to_time(o)
70
+
71
+ t = o
72
+ t = parse(t) if t.is_a?(String)
73
+ t = Time.now + t if t.is_a?(Numeric)
74
+
75
+ raise ArgumentError.new(
76
+ "cannot turn #{o.inspect} to a point in time, doesn't make sense"
77
+ ) unless t.is_a?(Time)
78
+
79
+ t
80
+ end
81
+
82
+ DURATIONS2M = [
83
+ [ 'y', 365 * 24 * 3600 ],
84
+ [ 'M', 30 * 24 * 3600 ],
85
+ [ 'w', 7 * 24 * 3600 ],
86
+ [ 'd', 24 * 3600 ],
87
+ [ 'h', 3600 ],
88
+ [ 'm', 60 ],
89
+ [ 's', 1 ]
90
+ ]
91
+ DURATIONS2 = DURATIONS2M.dup
92
+ DURATIONS2.delete_at(1)
93
+
94
+ DURATIONS = DURATIONS2M.inject({}) { |r, (k, v)| r[k] = v; r }
95
+ DURATION_LETTERS = DURATIONS.keys.join
96
+
97
+ DU_KEYS = DURATIONS2M.collect { |k, v| k.to_sym }
98
+
99
+ # Turns a string like '1m10s' into a float like '70.0', more formally,
100
+ # turns a time duration expressed as a string into a Float instance
101
+ # (millisecond count).
102
+ #
103
+ # w -> week
104
+ # d -> day
105
+ # h -> hour
106
+ # m -> minute
107
+ # s -> second
108
+ # M -> month
109
+ # y -> year
110
+ # 'nada' -> millisecond
111
+ #
112
+ # Some examples:
113
+ #
114
+ # Rufus::Scheduler.parse_duration "0.5" # => 0.5
115
+ # Rufus::Scheduler.parse_duration "500" # => 0.5
116
+ # Rufus::Scheduler.parse_duration "1000" # => 1.0
117
+ # Rufus::Scheduler.parse_duration "1h" # => 3600.0
118
+ # Rufus::Scheduler.parse_duration "1h10s" # => 3610.0
119
+ # Rufus::Scheduler.parse_duration "1w2d" # => 777600.0
120
+ #
121
+ # Negative time strings are OK (Thanks Danny Fullerton):
122
+ #
123
+ # Rufus::Scheduler.parse_duration "-0.5" # => -0.5
124
+ # Rufus::Scheduler.parse_duration "-1h" # => -3600.0
125
+ #
126
+ def self.parse_duration(string, opts={})
127
+
128
+ string = string.to_s
129
+
130
+ return 0.0 if string == ''
131
+
132
+ m = string.match(/^(-?)([\d\.#{DURATION_LETTERS}]+)$/)
133
+
134
+ return nil if m.nil? && opts[:no_error]
135
+ raise ArgumentError.new("cannot parse '#{string}'") if m.nil?
136
+
137
+ mod = m[1] == '-' ? -1.0 : 1.0
138
+ val = 0.0
139
+
140
+ s = m[2]
141
+
142
+ while s.length > 0
143
+ m = nil
144
+ if m = s.match(/^(\d+|\d+\.\d*|\d*\.\d+)([#{DURATION_LETTERS}])(.*)$/)
145
+ val += m[1].to_f * DURATIONS[m[2]]
146
+ elsif s.match(/^\d+$/)
147
+ val += s.to_i
148
+ elsif s.match(/^\d*\.\d*$/)
149
+ val += s.to_f
150
+ elsif opts[:no_error]
151
+ return nil
152
+ else
153
+ raise ArgumentError.new(
154
+ "cannot parse '#{string}' (especially '#{s}')"
155
+ )
156
+ end
157
+ break unless m && m[3]
158
+ s = m[3]
159
+ end
160
+
161
+ mod * val
162
+ end
163
+
164
+ class << self
165
+ #-
166
+ # for compatibility with rufus-scheduler 2.x
167
+ #+
168
+ alias parse_duration_string parse_duration
169
+ alias parse_time_string parse_duration
170
+ end
171
+
172
+
173
+ # Turns a number of seconds into a a time string
174
+ #
175
+ # Rufus.to_duration 0 # => '0s'
176
+ # Rufus.to_duration 60 # => '1m'
177
+ # Rufus.to_duration 3661 # => '1h1m1s'
178
+ # Rufus.to_duration 7 * 24 * 3600 # => '1w'
179
+ # Rufus.to_duration 30 * 24 * 3600 + 1 # => "4w2d1s"
180
+ #
181
+ # It goes from seconds to the year. Months are not counted (as they
182
+ # are of variable length). Weeks are counted.
183
+ #
184
+ # For 30 days months to be counted, the second parameter of this
185
+ # method can be set to true.
186
+ #
187
+ # Rufus.to_duration 30 * 24 * 3600 + 1, true # => "1M1s"
188
+ #
189
+ # If a Float value is passed, milliseconds will be displayed without
190
+ # 'marker'
191
+ #
192
+ # Rufus.to_duration 0.051 # => "51"
193
+ # Rufus.to_duration 7.051 # => "7s51"
194
+ # Rufus.to_duration 0.120 + 30 * 24 * 3600 + 1 # => "4w2d1s120"
195
+ #
196
+ # (this behaviour mirrors the one found for parse_time_string()).
197
+ #
198
+ # Options are :
199
+ #
200
+ # * :months, if set to true, months (M) of 30 days will be taken into
201
+ # account when building up the result
202
+ # * :drop_seconds, if set to true, seconds and milliseconds will be trimmed
203
+ # from the result
204
+ #
205
+ def self.to_duration(seconds, options={})
206
+
207
+ h = to_duration_hash(seconds, options)
208
+
209
+ return (options[:drop_seconds] ? '0m' : '0s') if h.empty?
210
+
211
+ s =
212
+ DU_KEYS.inject('') { |r, key|
213
+ count = h[key]
214
+ count = nil if count == 0
215
+ r << "#{count}#{key}" if count
216
+ r
217
+ }
218
+
219
+ ms = h[:ms]
220
+ s << ms.to_s if ms
221
+
222
+ s
223
+ end
224
+
225
+ class << self
226
+ #-
227
+ # for compatibility with rufus-scheduler 2.x
228
+ #+
229
+ alias to_duration_string to_duration
230
+ alias to_time_string to_duration
231
+ end
232
+
233
+ # Turns a number of seconds (integer or Float) into a hash like in :
234
+ #
235
+ # Rufus.to_duration_hash 0.051
236
+ # # => { :ms => "51" }
237
+ # Rufus.to_duration_hash 7.051
238
+ # # => { :s => 7, :ms => "51" }
239
+ # Rufus.to_duration_hash 0.120 + 30 * 24 * 3600 + 1
240
+ # # => { :w => 4, :d => 2, :s => 1, :ms => "120" }
241
+ #
242
+ # This method is used by to_duration behind the scenes.
243
+ #
244
+ # Options are :
245
+ #
246
+ # * :months, if set to true, months (M) of 30 days will be taken into
247
+ # account when building up the result
248
+ # * :drop_seconds, if set to true, seconds and milliseconds will be trimmed
249
+ # from the result
250
+ #
251
+ def self.to_duration_hash(seconds, options={})
252
+
253
+ h = {}
254
+
255
+ if seconds.is_a?(Float)
256
+ h[:ms] = (seconds % 1 * 1000).to_i
257
+ seconds = seconds.to_i
258
+ end
259
+
260
+ if options[:drop_seconds]
261
+ h.delete(:ms)
262
+ seconds = (seconds - seconds % 60)
263
+ end
264
+
265
+ durations = options[:months] ? DURATIONS2M : DURATIONS2
266
+
267
+ durations.each do |key, duration|
268
+
269
+ count = seconds / duration
270
+ seconds = seconds % duration
271
+
272
+ h[key.to_sym] = count if count > 0
273
+ end
274
+
275
+ h
276
+ end
277
+
278
+ #--
279
+ # misc
280
+ #++
281
+
282
+ # Produces the UTC string representation of a Time instance
283
+ #
284
+ # like "2009/11/23 11:11:50.947109 UTC"
285
+ #
286
+ def self.utc_to_s(t=Time.now)
287
+
288
+ "#{t.utc.strftime('%Y-%m-%d %H:%M:%S')}.#{sprintf('%06d', t.usec)} UTC"
289
+ end
290
+
291
+ # Produces a hour/min/sec/milli string representation of Time instance
292
+ #
293
+ def self.h_to_s(t=Time.now)
294
+
295
+ "#{t.strftime('%H:%M:%S')}.#{sprintf('%06d', t.usec)}"
296
+ end
297
+
298
+ # Debugging tools...
299
+ #
300
+ class D
301
+
302
+ def self.h_to_s(t=Time.now); Rufus::Scheduler.h_to_s(t); end
303
+ end
304
+ end
305
+ end
306
+
@@ -0,0 +1,174 @@
1
+ #--
2
+ # Copyright (c) 2006-2015, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ class Rufus::Scheduler
27
+
28
+ TIMEZONES = %w[
29
+ GB NZ UCT EET CET PRC ROC WET GMT EST ROK UTC MST HST MET Zulu Cuba Iran W-SU
30
+ Eire GMT0 Libya Japan Egypt GMT+0 GMT-0 Israel Poland Navajo Turkey GB-Eire
31
+ Iceland PST8PDT Etc/UCT CST6CDT NZ-CHAT MST7MDT Jamaica EST5EDT Etc/GMT Etc/UTC
32
+ US/Samoa Etc/GMT0 Portugal Hongkong Etc/Zulu Singapore Asia/Baku Etc/GMT-9
33
+ Etc/GMT+1 Etc/GMT+0 Asia/Aden Etc/GMT+2 Etc/GMT+3 Etc/GMT+4 Etc/GMT+5 Etc/GMT+6
34
+ Etc/GMT+7 Etc/GMT+8 Etc/GMT+9 Etc/GMT-0 Etc/GMT-1 Universal Asia/Dili Greenwich
35
+ Asia/Gaza Etc/GMT-8 Etc/GMT-7 US/Alaska Asia/Oral Etc/GMT-6 Etc/GMT-5 Etc/GMT-4
36
+ Asia/Hovd Etc/GMT-3 US/Hawaii Etc/GMT-2 Kwajalein Asia/Omsk Asia/Macao
37
+ Etc/GMT-14 Asia/Kabul US/Central Etc/GMT-13 US/Arizona Asia/Macau Asia/Qatar
38
+ Asia/Seoul Asia/Tokyo Asia/Dubai US/Pacific Etc/GMT-12 Etc/GMT-11 Etc/GMT-10
39
+ Asia/Dhaka Asia/Dacca Asia/Chita Etc/GMT+12 Etc/GMT+10 Asia/Amman Asia/Aqtau
40
+ Etc/GMT+11 US/Eastern Asia/Thimbu Asia/Brunei Asia/Tehran Asia/Beirut
41
+ Europe/Rome Europe/Riga Brazil/Acre Brazil/East Europe/Oslo Brazil/West
42
+ Africa/Lome Asia/Taipei Asia/Saigon Asia/Riyadh Asia/Aqtobe Asia/Anadyr
43
+ Europe/Kiev Asia/Almaty Africa/Juba Pacific/Yap US/Aleutian Asia/Muscat
44
+ US/Mountain Asia/Harbin Asia/Hebron Asia/Manila Asia/Kuwait Asia/Urumqi
45
+ US/Michigan Indian/Mahe SystemV/EST5 Asia/Kashgar Indian/Cocos Asia/Jakarta
46
+ Asia/Kolkata Asia/Kuching America/Atka Asia/Irkutsk Pacific/Apia Asia/Magadan
47
+ Africa/Dakar America/Lima Pacific/Fiji Pacific/Guam Europe/Vaduz Pacific/Niue
48
+ Asia/Nicosia Africa/Ceuta Pacific/Truk America/Adak Pacific/Wake Africa/Tunis
49
+ Africa/Cairo Asia/Colombo SystemV/AST4 SystemV/CST6 Asia/Karachi Asia/Rangoon
50
+ SystemV/MST7 Asia/Baghdad Europe/Malta Africa/Lagos Europe/Minsk SystemV/PST8
51
+ Canada/Yukon Asia/Tbilisi America/Nome Asia/Bahrain Africa/Accra Europe/Paris
52
+ Asia/Bangkok Asia/Bishkek Asia/Thimphu SystemV/YST9 Asia/Yerevan Asia/Yakutsk
53
+ Europe/Sofia Asia/Ust-Nera Australia/ACT Australia/LHI Europe/Tirane
54
+ Asia/Tel_Aviv Australia/NSW Africa/Luanda Asia/Tashkent Africa/Lusaka
55
+ Asia/Shanghai Africa/Malabo Asia/Sakhalin Africa/Maputo Africa/Maseru
56
+ SystemV/HST10 Africa/Kigali Africa/Niamey Pacific/Samoa America/Sitka
57
+ Pacific/Palau Pacific/Nauru Pacific/Efate Asia/Makassar Pacific/Chuuk
58
+ Africa/Harare Africa/Douala America/Aruba America/Thule America/Bahia
59
+ America/Jujuy America/Belem Asia/Katmandu America/Boise Indian/Comoro
60
+ Indian/Chagos Asia/Jayapura Europe/Zurich Asia/Istanbul Europe/Zagreb
61
+ Etc/Greenwich Europe/Warsaw Europe/Vienna Etc/Universal Asia/Dushanbe
62
+ Europe/Athens Europe/Berlin Africa/Bissau Asia/Damascus Africa/Banjul
63
+ Europe/Dublin Africa/Bangui Africa/Bamako Europe/Jersey Africa/Asmera
64
+ Europe/Lisbon Africa/Asmara Europe/London Asia/Ashgabat Asia/Calcutta
65
+ Europe/Madrid Europe/Monaco Europe/Moscow Europe/Prague Europe/Samara
66
+ Europe/Skopje Asia/Khandyga Canada/Pacific Africa/Abidjan America/Manaus
67
+ Asia/Chongqing Asia/Chungking Africa/Algiers America/Maceio US/Pacific-New
68
+ Africa/Conakry America/La_Paz America/Juneau America/Nassau America/Inuvik
69
+ Europe/Andorra Africa/Kampala Asia/Ashkhabad Asia/Hong_Kong America/Havana
70
+ Canada/Eastern Europe/Belfast Canada/Central Australia/West Asia/Jerusalem
71
+ Africa/Mbabane Asia/Kamchatka America/Virgin America/Guyana Asia/Kathmandu
72
+ Mexico/General America/Panama Europe/Nicosia America/Denver Europe/Tallinn
73
+ Africa/Nairobi America/Dawson Europe/Vatican Europe/Vilnius America/Cuiaba
74
+ Africa/Tripoli Pacific/Wallis Atlantic/Faroe Pacific/Tarawa Pacific/Tahiti
75
+ Pacific/Saipan Pacific/Ponape America/Cayman America/Cancun Asia/Pontianak
76
+ Asia/Pyongyang Asia/Vientiane Asia/Qyzylorda Pacific/Noumea America/Bogota
77
+ Pacific/Midway Pacific/Majuro Asia/Samarkand Indian/Mayotte Pacific/Kosrae
78
+ Asia/Singapore Indian/Reunion America/Belize America/Regina America/Recife
79
+ Pacific/Easter Mexico/BajaSur America/Merida Pacific/Chatham Pacific/Fakaofo
80
+ Pacific/Gambier America/Rosario Asia/Ulan_Bator Indian/Maldives Pacific/Norfolk
81
+ America/Antigua Asia/Phnom_Penh America/Phoenix America/Caracas America/Cayenne
82
+ Atlantic/Azores Pacific/Pohnpei Atlantic/Canary America/Chicago Atlantic/Faeroe
83
+ Africa/Windhoek America/Cordoba America/Creston Africa/Timbuktu America/Curacao
84
+ Africa/Sao_Tome Africa/Ndjamena SystemV/AST4ADT Europe/Uzhgorod Europe/Tiraspol
85
+ SystemV/CST6CDT Africa/Monrovia America/Detroit Europe/Sarajevo Australia/Eucla
86
+ America/Tijuana America/Toronto America/Godthab America/Grenada Europe/Istanbul
87
+ America/Ojinaga America/Tortola Australia/Perth Europe/Helsinki Australia/South
88
+ Europe/Guernsey SystemV/EST5EDT Europe/Chisinau SystemV/MST7MDT Europe/Busingen
89
+ Europe/Budapest Europe/Brussels America/Halifax America/Mendoza America/Noronha
90
+ America/Nipigon Canada/Atlantic America/Yakutat SystemV/PST8PDT SystemV/YST9YDT
91
+ Canada/Mountain Africa/Kinshasa Africa/Khartoum Africa/Gaborone Africa/Freetown
92
+ America/Iqaluit America/Jamaica US/East-Indiana Africa/El_Aaiun America/Knox_IN
93
+ Africa/Djibouti Africa/Blantyre America/Moncton America/Managua Asia/Choibalsan
94
+ America/Marigot Australia/North Europe/Belgrade America/Resolute
95
+ America/Mazatlan Pacific/Funafuti Pacific/Auckland Pacific/Honolulu
96
+ Pacific/Johnston America/Miquelon America/Santarem Mexico/BajaNorte
97
+ America/Santiago Antarctica/Troll America/Asuncion America/Atikokan
98
+ America/Montreal America/Barbados Africa/Bujumbura Pacific/Pitcairn
99
+ Asia/Ulaanbaatar Indian/Mauritius America/New_York Antarctica/Syowa
100
+ America/Shiprock Indian/Kerguelen Asia/Novosibirsk America/Anguilla
101
+ Indian/Christmas Asia/Vladivostok Asia/Ho_Chi_Minh Antarctica/Davis
102
+ Atlantic/Bermuda Europe/Amsterdam Antarctica/Casey America/St_Johns
103
+ Atlantic/Madeira America/Winnipeg America/St_Kitts Europe/Volgograd
104
+ Brazil/DeNoronha Europe/Bucharest Africa/Mogadishu America/St_Lucia
105
+ Atlantic/Stanley Europe/Stockholm Australia/Currie Europe/Gibraltar
106
+ Australia/Sydney Asia/Krasnoyarsk Australia/Darwin America/Dominica
107
+ America/Edmonton America/Eirunepe Europe/Podgorica America/Ensenada
108
+ Europe/Ljubljana Australia/Hobart Europe/Mariehamn Africa/Lubumbashi
109
+ America/Goose_Bay Europe/Luxembourg America/Menominee America/Glace_Bay
110
+ America/Fortaleza Africa/Nouakchott America/Matamoros Pacific/Galapagos
111
+ America/Guatemala Pacific/Kwajalein Pacific/Marquesas America/Guayaquil
112
+ Asia/Kuala_Lumpur Europe/San_Marino America/Monterrey Europe/Simferopol
113
+ America/Araguaina Antarctica/Vostok Europe/Copenhagen America/Catamarca
114
+ Pacific/Pago_Pago America/Sao_Paulo America/Boa_Vista America/St_Thomas
115
+ Chile/Continental America/Vancouver Africa/Casablanca Europe/Bratislava
116
+ Pacific/Enderbury Pacific/Rarotonga Europe/Zaporozhye US/Indiana-Starke
117
+ Antarctica/Palmer Asia/Novokuznetsk Africa/Libreville America/Chihuahua
118
+ America/Anchorage Pacific/Tongatapu Antarctica/Mawson Africa/Porto-Novo
119
+ Asia/Yekaterinburg America/Paramaribo America/Hermosillo Atlantic/Jan_Mayen
120
+ Antarctica/McMurdo America/Costa_Rica Antarctica/Rothera America/Grand_Turk
121
+ Atlantic/Reykjavik Atlantic/St_Helena Australia/Victoria Chile/EasterIsland
122
+ Asia/Ujung_Pandang Australia/Adelaide America/Montserrat America/Porto_Acre
123
+ Africa/Brazzaville Australia/Brisbane America/Kralendijk America/Montevideo
124
+ America/St_Vincent America/Louisville Australia/Canberra Australia/Tasmania
125
+ Europe/Isle_of_Man Europe/Kaliningrad Africa/Ouagadougou America/Rio_Branco
126
+ Pacific/Kiritimati Africa/Addis_Ababa America/Metlakatla America/Martinique
127
+ Asia/Srednekolymsk America/Guadeloupe America/Fort_Wayne Australia/Lindeman
128
+ America/Whitehorse Arctic/Longyearbyen America/Pangnirtung America/Mexico_City
129
+ America/Los_Angeles America/Rainy_River Atlantic/Cape_Verde Pacific/Guadalcanal
130
+ Indian/Antananarivo America/El_Salvador Australia/Lord_Howe Africa/Johannesburg
131
+ America/Tegucigalpa Canada/Saskatchewan America/Thunder_Bay Canada/Newfoundland
132
+ America/Puerto_Rico America/Yellowknife Australia/Melbourne America/Porto_Velho
133
+ Australia/Queensland Australia/Yancowinna America/Santa_Isabel
134
+ America/Blanc-Sablon America/Scoresbysund America/Danmarkshavn
135
+ Pacific/Port_Moresby Antarctica/Macquarie America/Buenos_Aires
136
+ Africa/Dar_es_Salaam America/Campo_Grande America/Dawson_Creek
137
+ America/Indianapolis Pacific/Bougainville America/Rankin_Inlet
138
+ America/Indiana/Knox America/Lower_Princes America/Coral_Harbour
139
+ America/St_Barthelemy Australia/Broken_Hill America/Cambridge_Bay
140
+ America/Indiana/Vevay America/Swift_Current America/Port_of_Spain
141
+ Antarctica/South_Pole America/Santo_Domingo Atlantic/South_Georgia
142
+ America/Port-au-Prince America/Bahia_Banderas America/Indiana/Winamac
143
+ America/Indiana/Marengo America/Argentina/Jujuy America/Argentina/Salta
144
+ Canada/East-Saskatchewan America/Indiana/Vincennes America/Argentina/Tucuman
145
+ America/Argentina/Ushuaia Antarctica/DumontDUrville America/Indiana/Tell_City
146
+ America/Argentina/Mendoza America/Argentina/Cordoba America/Indiana/Petersburg
147
+ America/Argentina/San_Luis America/Argentina/San_Juan America/Argentina/La_Rioja
148
+ America/North_Dakota/Center America/Kentucky/Monticello
149
+ America/North_Dakota/Beulah America/Kentucky/Louisville
150
+ America/Argentina/Catamarca America/Indiana/Indianapolis
151
+ America/North_Dakota/New_Salem America/Argentina/Rio_Gallegos
152
+ America/Argentina/Buenos_Aires America/Argentina/ComodRivadavia
153
+ ]
154
+
155
+ ##
156
+ ## http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations
157
+ #
158
+ #ABBREVIATIONS = %w[
159
+ #ACDT ACST ACT ADT AEDT AEST AFT AKDT AKST AMST AMST AMT AMT ART AST AST AWDT
160
+ #AWST AZOST AZT BDT BIOT BIT BOT BRT BST BST BTT CAT CCT CDT CDT CEDT CEST CET
161
+ #CHADT CHAST CHOT ChST CHUT CIST CIT CKT CLST CLT COST COT CST CST CST CST CST
162
+ #CT CVT CWST CXT DAVT DDUT DFT EASST EAST EAT ECT ECT EDT EEDT EEST EET EGST EGT
163
+ #EIT EST EST FET FJT FKST FKST FKT FNT GALT GAMT GET GFT GILT GIT GMT GST GST
164
+ #GYT HADT HAEC HAST HKT HMT HOVT HST ICT IDT IOT IRDT IRKT IRST IST IST IST JST
165
+ #KGT KOST KRAT KST LHST LHST LINT MAGT MART MAWT MDT MET MEST MHT MIST MIT MMT
166
+ #MSK MST MST MST MUT MVT MYT NCT NDT NFT NPT NST NT NUT NZDT NZST OMST ORAT PDT
167
+ #PET PETT PGT PHOT PKT PMDT PMST PONT PST PST PYST PYT RET ROTT SAKT SAMT SAST
168
+ #SBT SCT SGT SLST SRET SRT SST SST SYOT TAHT THA TFT TJT TKT TLT TMT TOT TVT UCT
169
+ #ULAT USZ1 UTC UYST UYT UZT VET VLAT VOLT VOST VUT WAKT WAST WAT WEDT WEST WET
170
+ #WIT WST YAKT YEKT Z
171
+ #].uniq
172
+
173
+ end
174
+
@@ -0,0 +1,154 @@
1
+ #--
2
+ # Copyright (c) 2006-2015, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+ require 'rufus/scheduler/zones'
26
+
27
+
28
+ class Rufus::Scheduler
29
+
30
+ #
31
+ # Zon{ing|ed}Time, whatever.
32
+ #
33
+ class ZoTime
34
+
35
+ attr_accessor :seconds
36
+ attr_accessor :zone
37
+
38
+ def initialize(s, zone)
39
+
40
+ @seconds = s.to_f
41
+ @zone = zone
42
+ end
43
+
44
+ def time
45
+
46
+ in_zone do
47
+
48
+ t = Time.at(@seconds)
49
+
50
+ if t.isdst
51
+ t1 = Time.at(@seconds + 3600)
52
+ t = t1 if t.zone != t1.zone && t.hour == t1.hour && t.min == t1.min
53
+ # ambiguous TZ (getting out of DST)
54
+ else
55
+ t.hour # force t to compute itself
56
+ end
57
+
58
+ t
59
+ end
60
+ end
61
+
62
+ def utc
63
+
64
+ time.utc
65
+ end
66
+
67
+ def add(s)
68
+
69
+ @seconds += s.to_f
70
+ end
71
+
72
+ def substract(s)
73
+
74
+ @seconds -= s.to_f
75
+ end
76
+
77
+ def to_f
78
+
79
+ @seconds
80
+ end
81
+
82
+ #DELTA_TZ_REX = /^[+-][0-1][0-9]:?[0-5][0-9]$/
83
+
84
+ def self.envtzable?(s)
85
+
86
+ TIMEZONES.include?(s)
87
+ end
88
+
89
+ def self.parse(str, opts={})
90
+
91
+ if defined?(::Chronic) && t = ::Chronic.parse(str, opts)
92
+ return ZoTime.new(t, ENV['TZ'])
93
+ end
94
+
95
+ begin
96
+ DateTime.parse(str)
97
+ rescue
98
+ raise ArgumentError, "no time information in #{o.inspect}"
99
+ end if RUBY_VERSION < '1.9.0'
100
+
101
+ zone = nil
102
+
103
+ s =
104
+ str.gsub(/\S+/) { |m|
105
+ if envtzable?(m)
106
+ zone ||= m
107
+ ''
108
+ else
109
+ m
110
+ end
111
+ }
112
+
113
+ return nil unless zone.nil? || is_timezone?(zone)
114
+
115
+ zt = ZoTime.new(0, zone || ENV['TZ'])
116
+ zt.in_zone { zt.seconds = Time.parse(s).to_f }
117
+
118
+ zt.seconds == nil ? nil : zt
119
+ end
120
+
121
+ def self.is_timezone?(str)
122
+
123
+ return false if str == nil
124
+
125
+ return true if Time.zone_offset(str)
126
+ return true if str == 'Zulu'
127
+
128
+ return !! (::TZInfo::Timezone.get(str) rescue nil) if defined?(::TZInfo)
129
+
130
+ zt = ZoTime.new(0, str)
131
+ t = zt.time
132
+
133
+ return false if t.zone == ''
134
+ return false if str.match(/[a-z]/) && str.start_with?(t.zone)
135
+
136
+ return false if RUBY_PLATFORM.include?('java') && ! envtzable?(str)
137
+
138
+ true
139
+ end
140
+
141
+ def in_zone(&block)
142
+
143
+ current_timezone = ENV['TZ']
144
+ ENV['TZ'] = @zone
145
+
146
+ block.call
147
+
148
+ ensure
149
+
150
+ ENV['TZ'] = current_timezone
151
+ end
152
+ end
153
+ end
154
+