rufus-scheduler 3.0.9 → 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.
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2006-2014, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2006-2015, John Mettraux, jmettraux@gmail.com
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2006-2014, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2006-2015, John Mettraux, jmettraux@gmail.com
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -46,32 +46,9 @@ module Rufus
46
46
  o.is_a?(String) ? parse_duration(o, opts) : o
47
47
  end
48
48
 
49
- TZ_REGEX = /\b((?:[a-zA-Z][a-zA-z0-9\-+]+)(?:\/[a-zA-Z0-9_\-+]+)?)\b/
50
-
51
49
  def self.parse_at(o, opts={})
52
50
 
53
- return o if o.is_a?(Time)
54
-
55
- # TODO: deal with tz if suffixed to Chronic string?
56
- return Chronic.parse(o, opts) if defined?(Chronic)
57
-
58
- tz = nil
59
- s =
60
- o.to_s.gsub(TZ_REGEX) { |m|
61
- t = TZInfo::Timezone.get(m) rescue nil
62
- tz ||= t
63
- t ? '' : m
64
- }
65
-
66
- begin
67
- DateTime.parse(o)
68
- rescue
69
- raise ArgumentError, "no time information in #{o.inspect}"
70
- end if RUBY_VERSION < '1.9.0'
71
-
72
- t = Time.parse(s)
73
-
74
- tz ? tz.local_to_utc(t) : t
51
+ Rufus::Scheduler::ZoTime.parse(o, opts).time
75
52
 
76
53
  rescue StandardError => se
77
54
 
@@ -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
+
@@ -26,38 +26,13 @@ job scheduler for Ruby (at, cron, in and every jobs).
26
26
  '*.gemspec', '*.txt', '*.rdoc', '*.md'
27
27
  ]
28
28
 
29
- s.add_runtime_dependency 'tzinfo'
29
+ #s.add_runtime_dependency 'tzinfo'
30
30
 
31
31
  s.add_development_dependency 'rake'
32
32
  s.add_development_dependency 'rspec', '>= 2.13.0'
33
33
  s.add_development_dependency 'chronic'
34
+ s.add_development_dependency 'tzinfo'
34
35
 
35
36
  s.require_path = 'lib'
36
-
37
- s.post_install_message =
38
- %{
39
- ***
40
-
41
- Thanks for installing rufus-scheduler #{s.version}
42
-
43
- It might not be 100% compatible with rufus-scheduler 2.x.
44
-
45
- If you encounter issues with this new rufus-scheduler, especially
46
- if your app worked fine with previous versions of it, you can
47
-
48
- A) Forget it and peg your Gemfile to rufus-scheduler 2.0.24
49
-
50
- and / or
51
-
52
- B) Take some time to carefully report the issue at
53
- https://github.com/jmettraux/rufus-scheduler/issues
54
-
55
- For general help about rufus-scheduler, ask via:
56
- http://stackoverflow.com/questions/ask?tags=rufus-scheduler+ruby
57
-
58
- Cheers.
59
-
60
- ***
61
- }
62
37
  end
63
38
 
@@ -5,7 +5,6 @@
5
5
  # Sat Mar 21 12:55:27 JST 2009
6
6
  #
7
7
 
8
- require 'tzinfo'
9
8
  require 'spec_helper'
10
9
 
11
10
 
@@ -15,6 +14,24 @@ describe Rufus::Scheduler::CronLine do
15
14
  Rufus::Scheduler::CronLine.new(cronline_string)
16
15
  end
17
16
 
17
+ def nt(cronline, now)
18
+ Rufus::Scheduler::CronLine.new(cronline).next_time(now)
19
+ end
20
+ def ntz(cronline, now)
21
+ tz = cronline.split.last
22
+ tu = nt(cronline, now).utc
23
+ in_zone(tz) { tu.getlocal }
24
+ end
25
+
26
+ def pt(cronline, now)
27
+ Rufus::Scheduler::CronLine.new(cronline).previous_time(now)
28
+ end
29
+ def ptz(cronline, now)
30
+ tz = cronline.split.last
31
+ tu = pt(cronline, now).utc
32
+ in_zone(tz) { tu.getlocal }
33
+ end
34
+
18
35
  def match(line, time)
19
36
  expect(cl(line).matches?(time)).to eq(true)
20
37
  end
@@ -49,12 +66,20 @@ describe Rufus::Scheduler::CronLine do
49
66
 
50
67
  to_a '0 0 1 1 *', [ [0], [0], [0], [1], [1], nil, nil, nil ]
51
68
 
52
- to_a '0 23-24 * * *', [ [0], [0], [23, 0], nil, nil, nil, nil, nil ]
69
+ if ruby18?
70
+ to_a '0 23-24 * * *', [ [0], [0], [0, 23], nil, nil, nil, nil, nil ]
71
+ else
72
+ to_a '0 23-24 * * *', [ [0], [0], [23, 0], nil, nil, nil, nil, nil ]
73
+ end
53
74
  #
54
75
  # as reported by Aimee Rose in
55
76
  # https://github.com/jmettraux/rufus-scheduler/issues/56
56
77
 
57
- to_a '0 23-2 * * *', [ [0], [0], [23, 0, 1, 2], nil, nil, nil, nil, nil ]
78
+ if ruby18?
79
+ to_a '0 23-2 * * *', [ [0], [0], [0, 1, 2, 23], nil, nil, nil, nil, nil ]
80
+ else
81
+ to_a '0 23-2 * * *', [ [0], [0], [23, 0, 1, 2], nil, nil, nil, nil, nil ]
82
+ end
58
83
  end
59
84
 
60
85
  it 'rejects invalid weekday expressions' do
@@ -92,7 +117,10 @@ describe Rufus::Scheduler::CronLine do
92
117
 
93
118
  to_a(
94
119
  '0 */2 * * *',
95
- [ [0], [0], (0..11).collect { |e| e * 2 }, nil, nil, nil, nil, nil ])
120
+ [ [0], [0], (0..23).select { |e| e.even? }, nil, nil, nil, nil, nil ])
121
+ to_a(
122
+ '0 0-23/2 * * *',
123
+ [ [0], [0], (0..23).select { |e| e.even? }, nil, nil, nil, nil, nil ])
96
124
  to_a(
97
125
  '0 7-23/2 * * *',
98
126
  [ [0], [0], (7..23).select { |e| e.odd? }, nil, nil, nil, nil, nil ])
@@ -189,56 +217,34 @@ describe Rufus::Scheduler::CronLine do
189
217
 
190
218
  describe '#next_time' do
191
219
 
192
- def nt(cronline, now)
193
- Rufus::Scheduler::CronLine.new(cronline).next_time(now)
194
- end
195
- def ntz(cronline, now)
196
- tz = cronline.split.last
197
- tu = nt(cronline, now).utc
198
- in_zone(tz) { tu.getlocal }
199
- end
200
-
201
220
  it 'computes the next occurence correctly' do
202
221
 
203
- now = Time.at(0).getutc # Thu Jan 01 00:00:00 UTC 1970
204
-
205
- expect(nt('* * * * *', now)).to eq(now + 60)
206
- expect(nt('* * * * sun', now)).to eq(now + 259200)
207
- expect(nt('* * * * * *', now)).to eq(now + 1)
208
- expect(nt('* * 13 * fri', now)).to eq(now + 3715200)
209
-
210
- expect(nt('10 12 13 12 *', now)).to eq(now + 29938200)
211
- # this one is slow (1 year == 3 seconds)
212
- #
213
- # historical note:
214
- # (comment made in 2006 or 2007, the underlying libs got better and
215
- # that slowness is gone)
216
-
217
- expect(nt('0 0 * * thu', now)).to eq(now + 604800)
218
- expect(nt('00 0 * * thu', now)).to eq(now + 604800)
222
+ in_zone 'Europe/Berlin' do
219
223
 
220
- expect(nt('0 0 * * *', now)).to eq(now + 24 * 3600)
221
- expect(nt('0 24 * * *', now)).to eq(now + 24 * 3600)
224
+ now = Time.at(0) - 3600
222
225
 
223
- now = local(2008, 12, 31, 23, 59, 59, 0)
226
+ expect(nt('* * * * *', now)).to eq(now + 60)
227
+ expect(nt('* * * * sun', now)).to eq(now + 259200)
228
+ expect(nt('* * * * * *', now)).to eq(now + 1)
229
+ expect(nt('* * 13 * fri', now)).to eq(now + 3715200)
224
230
 
225
- expect(nt('* * * * *', now)).to eq(now + 1)
226
- end
231
+ expect(nt('10 12 13 12 *', now)).to eq(now + 29938200)
232
+ # this one is slow (1 year == 3 seconds)
233
+ #
234
+ # historical note:
235
+ # (comment made in 2006 or 2007, the underlying libs got better and
236
+ # that slowness is gone)
227
237
 
228
- it 'computes the next occurence correctly in UTC (TZ not specified)' do
238
+ expect(nt('0 0 * * thu', now)).to eq(now + 604800)
239
+ expect(nt('00 0 * * thu', now)).to eq(now + 604800)
229
240
 
230
- now = utc(1970, 1, 1)
241
+ expect(nt('0 0 * * *', now)).to eq(now + 24 * 3600)
242
+ expect(nt('0 24 * * *', now)).to eq(now + 24 * 3600)
231
243
 
232
- expect(nt('* * * * *', now)).to eq(utc(1970, 1, 1, 0, 1))
233
- expect(nt('* * * * sun', now)).to eq(utc(1970, 1, 4))
234
- expect(nt('* * * * * *', now)).to eq(utc(1970, 1, 1, 0, 0, 1))
235
- expect(nt('* * 13 * fri', now)).to eq(utc(1970, 2, 13))
236
-
237
- expect(nt('10 12 13 12 *', now)).to eq(utc(1970, 12, 13, 12, 10))
238
- # this one is slow (1 year == 3 seconds)
239
- expect(nt('* * 1 6 *', now)).to eq(utc(1970, 6, 1))
244
+ now = local(2008, 12, 31, 23, 59, 59, 0)
240
245
 
241
- expect(nt('0 0 * * thu', now)).to eq(utc(1970, 1, 8))
246
+ expect(nt('* * * * *', now)).to eq(now + 1)
247
+ end
242
248
  end
243
249
 
244
250
  it 'computes the next occurence correctly in local TZ (TZ not specified)' do
@@ -260,9 +266,7 @@ describe Rufus::Scheduler::CronLine do
260
266
  it 'computes the next occurence correctly in UTC (TZ specified)' do
261
267
 
262
268
  zone = 'Europe/Stockholm'
263
- tz = TZInfo::Timezone.get(zone)
264
- now = tz.local_to_utc(local(1970, 1, 1))
265
- # Midnight in zone, UTC
269
+ now = in_zone(zone) { Time.local(1970, 1, 1) }
266
270
 
267
271
  expect(nt("* * * * * #{zone}", now)).to eq(utc(1969, 12, 31, 23, 1))
268
272
  expect(nt("* * * * sun #{zone}", now)).to eq(utc(1970, 1, 3, 23))
@@ -275,20 +279,6 @@ describe Rufus::Scheduler::CronLine do
275
279
  expect(nt("0 0 * * thu #{zone}", now)).to eq(utc(1970, 1, 7, 23))
276
280
  end
277
281
 
278
- #it 'computes the next occurence correctly in local TZ (TZ specified)' do
279
- # zone = 'Europe/Stockholm'
280
- # tz = TZInfo::Timezone.get(zone)
281
- # now = tz.local_to_utc(utc(1970, 1, 1)).localtime
282
- # # Midnight in zone, local time
283
- # nt("* * * * * #{zone}", now).should == local(1969, 12, 31, 18, 1)
284
- # nt("* * * * sun #{zone}", now).should == local(1970, 1, 3, 18)
285
- # nt("* * * * * * #{zone}", now).should == local(1969, 12, 31, 18, 0, 1)
286
- # nt("* * 13 * fri #{zone}", now).should == local(1970, 2, 12, 18)
287
- # nt("10 12 13 12 * #{zone}", now).should == local(1970, 12, 13, 6, 10)
288
- # nt("* * 1 6 * #{zone}", now).should == local(1970, 5, 31, 19)
289
- # nt("0 0 * * thu #{zone}", now).should == local(1970, 1, 7, 18)
290
- #end
291
-
292
282
  it 'computes the next time correctly when there is a sun#2 involved' do
293
283
 
294
284
  expect(nt('* * * * sun#1', local(1970, 1, 1))).to eq(local(1970, 1, 4))
@@ -375,15 +365,6 @@ describe Rufus::Scheduler::CronLine do
375
365
 
376
366
  describe '#previous_time' do
377
367
 
378
- def pt(cronline, now)
379
- Rufus::Scheduler::CronLine.new(cronline).previous_time(now)
380
- end
381
- def ptz(cronline, now)
382
- tz = cronline.split.last
383
- tu = pt(cronline, now).utc
384
- in_zone(tz) { tu.getlocal }
385
- end
386
-
387
368
  it 'returns the previous time the cron should have triggered' do
388
369
 
389
370
  expect(
@@ -438,21 +419,21 @@ describe Rufus::Scheduler::CronLine do
438
419
 
439
420
  describe '#matches?' do
440
421
 
441
- it 'matches correctly in UTC (TZ not specified)' do
442
-
443
- match '* * * * *', utc(1970, 1, 1, 0, 1)
444
- match '* * * * sun', utc(1970, 1, 4)
445
- match '* * * * * *', utc(1970, 1, 1, 0, 0, 1)
446
- match '* * 13 * fri', utc(1970, 2, 13)
447
-
448
- match '10 12 13 12 *', utc(1970, 12, 13, 12, 10)
449
- match '* * 1 6 *', utc(1970, 6, 1)
450
-
451
- match '0 0 * * thu', utc(1970, 1, 8)
452
-
453
- match '0 0 1 1 *', utc(2012, 1, 1)
454
- no_match '0 0 1 1 *', utc(2012, 1, 1, 1, 0)
455
- end
422
+ # it 'matches correctly in UTC (TZ not specified)' do
423
+ #
424
+ # match '* * * * *', utc(1970, 1, 1, 0, 1)
425
+ # match '* * * * sun', utc(1970, 1, 4)
426
+ # match '* * * * * *', utc(1970, 1, 1, 0, 0, 1)
427
+ # match '* * 13 * fri', utc(1970, 2, 13)
428
+ #
429
+ # match '10 12 13 12 *', utc(1970, 12, 13, 12, 10)
430
+ # match '* * 1 6 *', utc(1970, 6, 1)
431
+ #
432
+ # match '0 0 * * thu', utc(1970, 1, 8)
433
+ #
434
+ # match '0 0 1 1 *', utc(2012, 1, 1)
435
+ # no_match '0 0 1 1 *', utc(2012, 1, 1, 1, 0)
436
+ # end
456
437
 
457
438
  it 'matches correctly in local TZ (TZ not specified)' do
458
439
 
@@ -546,19 +527,19 @@ describe Rufus::Scheduler::CronLine do
546
527
  it 'returns the shortest delta between two occurrences' do
547
528
 
548
529
  expect(Rufus::Scheduler::CronLine.new(
549
- '* * * * *').frequency).to eq(60)
530
+ '* * * * *').frequency).to eq(60)
550
531
  expect(Rufus::Scheduler::CronLine.new(
551
- '* * * * * *').frequency).to eq(1)
532
+ '* * * * * *').frequency).to eq(1)
552
533
 
553
534
  expect(Rufus::Scheduler::CronLine.new(
554
- '5 23 * * *').frequency).to eq(24 * 3600)
535
+ '5 23 * * *').frequency).to eq(24 * 3600)
555
536
  expect(Rufus::Scheduler::CronLine.new(
556
- '5 * * * *').frequency).to eq(3600)
537
+ '5 * * * *').frequency).to eq(3600)
557
538
  expect(Rufus::Scheduler::CronLine.new(
558
- '10,20,30 * * * *').frequency).to eq(600)
539
+ '10,20,30 * * * *').frequency).to eq(600)
559
540
 
560
541
  expect(Rufus::Scheduler::CronLine.new(
561
- '10,20,30 * * * * *').frequency).to eq(10)
542
+ '10,20,30 * * * * *').frequency).to eq(10)
562
543
  end
563
544
  end
564
545
 
@@ -567,22 +548,30 @@ describe Rufus::Scheduler::CronLine do
567
548
  it 'returns the shortest delta between two occurrences' do
568
549
 
569
550
  expect(Rufus::Scheduler::CronLine.new(
570
- '* * * * *').brute_frequency).to eq(60)
551
+ '* * * * *').brute_frequency).to eq(60)
571
552
  expect(Rufus::Scheduler::CronLine.new(
572
- '* * * * * *').brute_frequency).to eq(1)
553
+ '* * * * * *').brute_frequency).to eq(1)
573
554
 
574
555
  expect(Rufus::Scheduler::CronLine.new(
575
- '5 23 * * *').brute_frequency).to eq(24 * 3600)
556
+ '5 23 * * *').brute_frequency).to eq(24 * 3600)
576
557
  expect(Rufus::Scheduler::CronLine.new(
577
- '5 * * * *').brute_frequency).to eq(3600)
558
+ '5 * * * *').brute_frequency).to eq(3600)
578
559
  expect(Rufus::Scheduler::CronLine.new(
579
- '10,20,30 * * * *').brute_frequency).to eq(600)
560
+ '10,20,30 * * * *').brute_frequency).to eq(600)
580
561
 
581
562
  #Rufus::Scheduler::CronLine.new(
582
563
  # '10,20,30 * * * * *').brute_frequency.should == 10
583
564
  #
584
565
  # takes > 20s ...
585
566
  end
567
+
568
+ # some combos only appear every other year...
569
+ #
570
+ it 'does not go into an infinite loop' do
571
+
572
+ expect(Rufus::Scheduler::CronLine.new(
573
+ '1 2 3 4 5').brute_frequency).to eq(31622400)
574
+ end
586
575
  end
587
576
 
588
577
  context 'summer time' do
@@ -593,10 +582,6 @@ describe Rufus::Scheduler::CronLine do
593
582
  #
594
583
  it 'schedules correctly through a switch into summer time' do
595
584
 
596
- #j = `zdump -v Europe/Berlin | grep "Sun Mar" | grep 2014`.split("\n")[0]
597
- #j = j.match(/^.+ (Sun Mar .+ UTC) /)[1]
598
- # only works on system that have a zdump...
599
-
600
585
  in_zone 'Europe/Berlin' do
601
586
 
602
587
  # find the summer jump
@@ -623,14 +608,14 @@ describe Rufus::Scheduler::CronLine do
623
608
  n0 = cl0.next_time(friday)
624
609
  n1 = cl1.next_time(friday)
625
610
 
626
- expect(n0.strftime('%H:%M:%S %^a')).to eq('00:02:00 MON')
611
+ expect(n0.strftime('%H:%M:%S %^a')).to eq('00:02:00 TUE')
627
612
  expect(n1.strftime('%H:%M:%S %^a')).to eq('08:45:00 MON')
628
613
 
629
614
  expect(n0.isdst).to eq(true)
630
615
  expect(n1.isdst).to eq(true)
631
616
 
632
617
  expect(
633
- (n0 - 24 * 3600 * 3).strftime('%H:%M:%S %^a')).to eq('23:02:00 THU')
618
+ (n0 - 24 * 3600 * 3).strftime('%H:%M:%S %^a')).to eq('23:02:00 FRI')
634
619
  expect(
635
620
  (n1 - 24 * 3600 * 3).strftime('%H:%M:%S %^a')).to eq('07:45:00 FRI')
636
621
  end
@@ -676,6 +661,70 @@ describe Rufus::Scheduler::CronLine do
676
661
  (n1 - 24 * 3600 * 3).strftime('%H:%M:%S %^a')).to eq('09:45:00 FRI')
677
662
  end
678
663
  end
664
+
665
+ it 'correctly increments through a DST transition' do
666
+
667
+ expect(
668
+ nt('* * * * * America/Los_Angeles', Time.utc(2015, 3, 8, 9, 59))
669
+ ).to eq(Time.utc(2015, 3, 8, 10, 00))
670
+ end
671
+
672
+ it 'correctly increments every minute through a DST transition' do
673
+
674
+ in_zone 'America/Los_Angeles' do
675
+
676
+ line = cl('* * * * * America/Los_Angeles')
677
+
678
+ t = Time.local(2015, 3, 8, 1, 57)
679
+
680
+ points =
681
+ [ 0, 1, 2, 3 ].collect do
682
+ t = line.next_time(t)
683
+ t.strftime('%H:%M:%Sl') + ' ' + t.dup.utc.strftime('%H:%M:%Su')
684
+ end
685
+
686
+ expect(points).to eq(
687
+ [
688
+ '01:58:00l 09:58:00u',
689
+ '01:59:00l 09:59:00u',
690
+ '03:00:00l 10:00:00u',
691
+ '03:01:00l 10:01:00u'
692
+ ]
693
+ )
694
+ end
695
+ end
696
+
697
+ it 'correctly decrements through a DST transition' do
698
+
699
+ expect(
700
+ pt('* * * * * America/Los_Angeles', Time.utc(2015, 3, 8, 10, 00))
701
+ ).to eq(Time.utc(2015, 3, 8, 9, 59))
702
+ end
703
+
704
+ it 'correctly decrements every minute through a DST transition' do
705
+
706
+ in_zone 'America/Los_Angeles' do
707
+
708
+ line = cl('* * * * * America/Los_Angeles')
709
+
710
+ t = Time.local(2015, 3, 8, 3, 2)
711
+
712
+ points =
713
+ [ 0, 1, 2, 3 ].collect do
714
+ t = line.previous_time(t)
715
+ t.strftime('%H:%M:%Sl') + ' ' + t.dup.utc.strftime('%H:%M:%Su')
716
+ end
717
+
718
+ expect(points).to eq(
719
+ [
720
+ '03:01:00l 10:01:00u',
721
+ '03:00:00l 10:00:00u',
722
+ '01:59:00l 09:59:00u',
723
+ '01:58:00l 09:58:00u'
724
+ ]
725
+ )
726
+ end
727
+ end
679
728
  end
680
729
  end
681
730