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.
- data/CHANGELOG.txt +7 -0
- data/CREDITS.txt +3 -0
- data/LICENSE.txt +1 -1
- data/README.md +6 -13
- data/lib/rufus/scheduler.rb +4 -3
- data/lib/rufus/scheduler/cronline.rb +78 -74
- data/lib/rufus/scheduler/job_array.rb +2 -1
- data/lib/rufus/scheduler/jobs.rb +16 -15
- data/lib/rufus/scheduler/locks.rb +1 -1
- data/lib/rufus/scheduler/util.rb +2 -25
- data/lib/rufus/scheduler/zones.rb +174 -0
- data/lib/rufus/scheduler/zotime.rb +154 -0
- data/rufus-scheduler.gemspec +2 -27
- data/spec/cronline_spec.rb +152 -103
- data/spec/job_cron_spec.rb +22 -0
- data/spec/job_every_spec.rb +14 -0
- data/spec/job_repeat_spec.rb +1 -0
- data/spec/parse_spec.rb +28 -30
- data/spec/schedule_at_spec.rb +1 -1
- data/spec/scheduler_spec.rb +4 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/zotime_spec.rb +396 -0
- metadata +15 -18
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2006-
|
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
|
data/lib/rufus/scheduler/util.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2006-
|
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
|
-
|
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
|
+
|
data/rufus-scheduler.gemspec
CHANGED
@@ -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
|
|
data/spec/cronline_spec.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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..
|
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
|
-
|
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
|
-
|
221
|
-
expect(nt('0 24 * * *', now)).to eq(now + 24 * 3600)
|
224
|
+
now = Time.at(0) - 3600
|
222
225
|
|
223
|
-
|
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
|
-
|
226
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
530
|
+
'* * * * *').frequency).to eq(60)
|
550
531
|
expect(Rufus::Scheduler::CronLine.new(
|
551
|
-
|
532
|
+
'* * * * * *').frequency).to eq(1)
|
552
533
|
|
553
534
|
expect(Rufus::Scheduler::CronLine.new(
|
554
|
-
|
535
|
+
'5 23 * * *').frequency).to eq(24 * 3600)
|
555
536
|
expect(Rufus::Scheduler::CronLine.new(
|
556
|
-
|
537
|
+
'5 * * * *').frequency).to eq(3600)
|
557
538
|
expect(Rufus::Scheduler::CronLine.new(
|
558
|
-
|
539
|
+
'10,20,30 * * * *').frequency).to eq(600)
|
559
540
|
|
560
541
|
expect(Rufus::Scheduler::CronLine.new(
|
561
|
-
|
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
|
-
|
551
|
+
'* * * * *').brute_frequency).to eq(60)
|
571
552
|
expect(Rufus::Scheduler::CronLine.new(
|
572
|
-
|
553
|
+
'* * * * * *').brute_frequency).to eq(1)
|
573
554
|
|
574
555
|
expect(Rufus::Scheduler::CronLine.new(
|
575
|
-
|
556
|
+
'5 23 * * *').brute_frequency).to eq(24 * 3600)
|
576
557
|
expect(Rufus::Scheduler::CronLine.new(
|
577
|
-
|
558
|
+
'5 * * * *').brute_frequency).to eq(3600)
|
578
559
|
expect(Rufus::Scheduler::CronLine.new(
|
579
|
-
|
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
|
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
|
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
|
|