croner 4.4.1 → 5.0.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.
package/README.md CHANGED
@@ -14,7 +14,7 @@ Trigger functions and/or evaluate cron expressions in JavaScript. No dependencie
14
14
  * Works in Node.js >=6.0 (both require and import).
15
15
  * Works in Deno >=1.16.
16
16
  * Works in browsers as standalone, UMD or ES-module.
17
- * **Experimental feature:** Schedule in specific target timezones.
17
+ * Schedule using specific target timezones.
18
18
  * Includes [TypeScript](https://www.typescriptlang.org/) typings.
19
19
 
20
20
  Quick examples:
@@ -120,7 +120,7 @@ const job : Cron = new Cron("* * * * * *", () => {
120
120
  JavaScript
121
121
 
122
122
  ```javascript
123
- import Cron from "https://cdn.jsdelivr.net/gh/hexagon/croner@4/src/croner.js";
123
+ import Cron from "https://deno.land/x/croner@5.0.0/src/croner.js";
124
124
 
125
125
  Cron("* * * * * *", () => {
126
126
  console.log("This will run every second.");
@@ -130,7 +130,7 @@ Cron("* * * * * *", () => {
130
130
  TypeScript
131
131
 
132
132
  ```typescript
133
- import { Cron } from "https://cdn.jsdelivr.net/gh/hexagon/croner@4/src/croner.js";
133
+ import { Cron } from "https://deno.land/x/croner@5.0.0/src/croner.js";
134
134
 
135
135
  const _scheduler : Cron = new Cron("* * * * * *", () => {
136
136
  console.log("This will run every second.");
@@ -150,14 +150,14 @@ const _scheduler : Cron = new Cron("* * * * * *", () => {
150
150
  To use as a [UMD](https://github.com/umdjs/umd)-module (stand alone, [RequireJS](https://requirejs.org/) etc.)
151
151
 
152
152
  ```html
153
- <script src="https://cdn.jsdelivr.net/npm/croner@4/dist/croner.min.js"></script>
153
+ <script src="https://cdn.jsdelivr.net/npm/croner@5/dist/croner.min.js"></script>
154
154
  ```
155
155
 
156
156
  To use as a [ES-module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules)
157
157
 
158
158
  ```html
159
159
  <script type="module">
160
- import Cron from "https://cdn.jsdelivr.net/npm/croner@4/dist/croner.min.mjs";
160
+ import Cron from "https://cdn.jsdelivr.net/npm/croner@5/dist/croner.min.mjs";
161
161
 
162
162
  // ... see usage section ...
163
163
  </script>
@@ -203,18 +203,18 @@ job.stop();
203
203
  | maxRuns | Infinite | Number | |
204
204
  | catch | false | Boolean | Catch and ignore unhandled errors in triggered function |
205
205
  | timezone | undefined | String | Timezone in Europe/Stockholm format |
206
- | startAt | undefined | String | ISO 8601 formatted datetime (2021-10-17T23:43:00)<br>in local or specified timezone |
207
- | stopAt | undefined | String | ISO 8601 formatted datetime (2021-10-17T23:43:00)<br>in local or specified timezone |
206
+ | startAt | undefined | String | ISO 8601 formatted datetime (2021-10-17T23:43:00)<br>in local time (according to timezone parameter if passed) |
207
+ | stopAt | undefined | String | ISO 8601 formatted datetime (2021-10-17T23:43:00)<br>in local time (according to timezone parameter if passed) |
208
208
  | interval | 0 | Number | Minimum number of seconds between triggers. |
209
209
  | paused | false | Boolean | If the job should be paused from start. |
210
210
  | context | undefined | Any | Passed as the second parameter to triggered function |
211
- | legacyMode | false | boolean | Combine day-of-month and day-of-week using OR, default is AND |
211
+ | legacyMode | true | boolean | Combine day-of-month and day-of-week using true = OR, false = AND |
212
212
 
213
213
  #### Pattern
214
214
 
215
215
  The expressions of Croner are very similar to the ones of Vixie Cron, with a few additions and changes listed below.
216
216
 
217
- * In croner, a combination of day-of-week and day-of-month will only trigger when both conditions match. An example: ```0 20 1 * MON``` will only trigger when monday occur the first day of any month. In Vixie Cron, it would trigger every monday AND the first day of every month. Vixie style can be enabled with `legacyMode: true` from version `4.2.0`. See issue [#53](https://github.com/Hexagon/croner/issues/53) for more information.
217
+ * In croner, a combination of day-of-week and day-of-month will only trigger when both conditions match. An example: ```0 20 1 * MON``` will only trigger when monday occur the first day of any month. In Vixie Cron, it would trigger every monday AND the first day of every month. Vixie style can be enabled with `legacyMode: true` from version `4.2.0` and is default from `5.0.0`. See issue [#53](https://github.com/Hexagon/croner/issues/53) for more information.
218
218
 
219
219
  * Croner expressions support the following additional modifiers
220
220
  - *?* A question mark is substituted with croner initialization time, as an example - `? ? * * * *` would be substituted with `25 8 * * * *` if time is `<any hour>:08:25` at the time of `new Cron('? ? * * * *', <...>)`. The question mark can be used in any field.
@@ -261,7 +261,7 @@ It is also possible to use the following "nicknames" as pattern.
261
261
  #### Expressions
262
262
  ```javascript
263
263
  // Run a function according to pattern
264
- Cron('15-45/10 */5 1,2,3 ? JAN-MAR SAT', function () {
264
+ Cron('15-45/10 */5 1,2,3 ? JAN-MAR SAT', { legacyMode: false }, function () {
265
265
  console.log('This will run every tenth second between second 15-45');
266
266
  console.log('every fifth minute of hour 1,2 and 3 when day of month');
267
267
  console.log('is the same as when Cron started, every saturday in January to March.');
@@ -271,7 +271,7 @@ Cron('15-45/10 */5 1,2,3 ? JAN-MAR SAT', function () {
271
271
  #### Interval
272
272
  ```javascript
273
273
  // Trigger on specific interval combined with cron expression
274
- Cron('* * * 7-16 * MON-FRI', { interval: 90 }, function () {
274
+ Cron('* * * 7-16 * MON-FRI', { interval: 90, legacyMode: false }, function () {
275
275
  console.log('This will trigger every 90th second at 7-16 on mondays to fridays.');
276
276
  });
277
277
  ```
@@ -281,8 +281,8 @@ Cron('* * * 7-16 * MON-FRI', { interval: 90 }, function () {
281
281
  // Find next month
282
282
  const nextMonth = Cron("@monthly").next(),
283
283
  nextSunday = Cron("@weekly").next(),
284
- nextSat29feb = Cron("0 0 0 29 2 6").next(),
285
- nextSunLastOfMonth = Cron("0 0 0 L * 7").next();
284
+ nextSat29feb = Cron("0 0 0 29 2 6", { legacyMode: false }).next(),
285
+ nextSunLastOfMonth = Cron("0 0 0 L * 7", { legacyMode: false }).next();
286
286
 
287
287
  console.log("First day of next month: " + nextMonth.toLocaleDateString());
288
288
  console.log("Next sunday: " + nextSunday.toLocaleDateString());
package/SECURITY.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  | Version | Supported |
6
6
  | ------- | ------------------ |
7
- | 4.0.x | :white_check_mark: |
7
+ | >= 4.x | :white_check_mark: |
8
8
  | < 4.0 | :x: |
9
9
 
10
10
  ## Reporting a Vulnerability
package/dist/croner.cjs CHANGED
@@ -6,11 +6,11 @@
6
6
 
7
7
  /* ------------------------------------------------------------------------------------
8
8
 
9
- minitz - 1.0.1 - MIT License - Hexagon <hexagon@56k.guru>
9
+ minitz 2.1.3 - MIT License - Hexagon <hexagon@56k.guru>
10
10
 
11
- Bundled manually, check for updates at https://github.com/Hexagon/minitz
11
+ Bundled manually, check https://github.com/Hexagon/minitz for updates
12
12
 
13
- ------------------------------------------------------------------------------------
13
+ ------------------------------------------------------------------------------------
14
14
 
15
15
  License:
16
16
 
@@ -26,91 +26,266 @@
26
26
  all copies or substantial portions of the Software.
27
27
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
28
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30
30
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31
31
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
32
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
33
33
  THE SOFTWARE.
34
34
 
35
- ------------------------------------------------------------------------------------ */
35
+ ------------------------------------------------------------------------------------ */
36
36
 
37
- const minitz = {};
37
+ /**
38
+ * @typedef {Object} TimePoint
39
+ * @property {Number} year - 1970--
40
+ * @property {Number} month - 1-12
41
+ * @property {Number} day - 1-31
42
+ * @property {Number} hour - 0-24
43
+ * @property {Number} minute - 0-60
44
+ * @property {Number} second - 0-60
45
+ * @property {string} timezone - Time zone in IANA database format 'Europe/Stockholm'
46
+ */
38
47
 
39
48
  /**
40
- * "Converts" a date to a specific time zone
41
- *
42
- * **Note:** The resulting Date object will have local time set to target timezone,
43
- * but any functions/formatting working with UTC time, or offset will be misleading.
44
- *
45
- * Only use this function to get a formatted local time string.
46
- *
47
- * Example:
48
- * let normalDate = new Date(); // d is a normal Date instance, with local timezone and correct utc representation
49
- * tzDate = minitz.toTZ(d, 'America/New_York') // d is a tainted Date instance, where getHours()
50
- * (for example) will return local time in new york, but getUTCHours()
51
- * will return something irrelevant.
52
- *
53
- * @public
54
- *
55
- * @param {date} date - Input date
56
- * @param {string} tzString - Timezone string in Europe/Stockholm format
57
- * @returns {date} - Date object with local time adjusted to target timezone. UTC time WILL be off.
58
- */
59
- minitz.toTZ = function (date, tzString) {
60
- return new Date(date.toLocaleString("sv-SE", {timeZone: tzString}));
49
+ * Converts a date/time from a specific timezone to a normal date object using the system local time
50
+ *
51
+ * Shortcut for minitz.fromTZ(minitz.tp(...));
52
+ *
53
+ * @constructor
54
+ *
55
+ * @param {Number} year - 1970--
56
+ * @param {Number} month - 1-12
57
+ * @param {Number} day - 1-31
58
+ * @param {Number} hour - 0-24
59
+ * @param {Number} minute - 0-60
60
+ * @param {Number} second - 0-60
61
+ * @param {string} timezone - Time zone in IANA database format 'Europe/Stockholm'
62
+ * @param {boolean} [throwOnInvalidTime] - Default is to return the adjusted time if the call happens during a Daylight-Saving-Time switch.
63
+ * E.g. Value "01:01:01" is returned if input time is 00:01:01 while one hour got actually
64
+ * skipped, going from 23:59:59 to 01:00:00. Setting this flag makes the library throw an exception instead.
65
+ * @returns {date} - Normal date object with correct UTC and system local time
66
+ *
67
+ */
68
+ function minitz(year, month, day, hour, minute, second, timezone, throwOnInvalidTime) {
69
+ return minitz.fromTZ(minitz.tp(year, month, day, hour, minute, second, timezone), throwOnInvalidTime);
70
+ }
71
+
72
+ /**
73
+ * Converts a date/time from a specific timezone to a normal date object using the system local time
74
+ *
75
+ * @public
76
+ * @static
77
+ *
78
+ * @param {string} localTimeString - ISO8601 formatted local time string, non UTC
79
+ * @param {string} timezone - Time zone in IANA database format 'Europe/Stockholm'
80
+ * @param {boolean} [throwOnInvalidTime] - Default is to return the adjusted time if the call happens during a Daylight-Saving-Time switch.
81
+ * E.g. Value "01:01:01" is returned if input time is 00:01:01 while one hour got actually
82
+ * skipped, going from 23:59:59 to 01:00:00. Setting this flag makes the library throw an exception instead.
83
+ * @return {date} - Normal date object
84
+ *
85
+ */
86
+ minitz.fromTZISO = (localTimeString, timezone, throwOnInvalidTime) => {
87
+ return minitz.fromTZ(parseISOLocal(localTimeString, timezone), throwOnInvalidTime);
61
88
  };
62
-
89
+
63
90
  /**
64
- * Reverse of toTZ
65
- *
66
- * @public
67
- *
68
- * @param {date} date - Tainted input date, where local time is time in target timezone
69
- * @param {string} tzString - Timezone string in Europe/Stockholm format
70
- * @param {boolean} [throwOnInvalidTime] - Default is to return adjusted time if input time is during an DST switch.
71
- * E.g. assume 01:01:01 if input is 00:01:01 but time actually
72
- * skips from 23:59:59 to 01:00:00. Setting this flag makes the library throw instead.
73
- * @returns {null|date} - Normal date object with correct UTC and Local time
74
- */
75
- minitz.fromTZ = function(inputDate, tzString, throwOnInvalidTime) {
76
-
77
- // Get initial offset between timezones starting from input time.
78
- // Then create a guessed local time by subtracting offset from input time
79
- // and try recreating input time using guessed local time and calculated offset.
80
- const
81
- inputDateWithOffset = new Date(inputDate.toLocaleString("sv-SE", {timeZone: tzString})),
82
- offset = inputDate.getTime() - inputDateWithOffset.getTime(),
83
- guessedLocalDate = new Date(inputDate.getTime() + offset),
84
- guessedInputDate = new Date(guessedLocalDate.toLocaleString("sv-SE", {timeZone: tzString}));
85
-
86
- // Check if recreated input time matches actual input time
87
- const
88
- guessedInputDateOffset = guessedInputDate.getTime() - inputDate.getTime();
89
- if (guessedInputDateOffset === 0) {
90
- // All good, return local time
91
+ * Converts a date/time from a specific timezone to a normal date object using the system local time
92
+ *
93
+ * @public
94
+ * @static
95
+ *
96
+ * @param {TimePoint} date - Object with specified timezone
97
+ * @param {boolean} [throwOnInvalidTime] - Default is to return the adjusted time if the call happens during a Daylight-Saving-Time switch.
98
+ * E.g. Value "01:01:01" is returned if input time is 00:01:01 while one hour got actually
99
+ * skipped, going from 23:59:59 to 01:00:00. Setting this flag makes the library throw an exception instead.
100
+ * @returns {date} - Normal date object
101
+ */
102
+ minitz.fromTZ = function(timePoint, throwOnInvalidTime) {
103
+
104
+ const
105
+
106
+ // Construct a fake Date object with UTC date/time set to local date/time in source timezone
107
+ inputDate = new Date(Date.UTC(
108
+ timePoint.year,
109
+ timePoint.month - 1,
110
+ timePoint.day,
111
+ timePoint.hour,
112
+ timePoint.minute,
113
+ timePoint.second
114
+ )),
115
+
116
+ // Get offset between UTC and source timezone
117
+ offset = getTimezoneOffset(timePoint.timezone, inputDate),
118
+
119
+ // Remove offset from inputDate to hopefully get a true date object
120
+ guessedLocalDate = new Date(inputDate.getTime() - offset),
121
+
122
+ // Get offset between UTC and guessed time in target timezone
123
+ guessedInputDateOffset = getTimezoneOffset(timePoint.timezone, guessedLocalDate);
124
+
125
+ // If offset between guessed true date object and UTC matches initial calculation, the guess
126
+ // was spot on
127
+ if ((guessedInputDateOffset - offset) === 0) {
91
128
  return guessedLocalDate;
92
129
  } else {
93
- // Not quite there yet, make a second try on guessing local time, adjust by the offset from previous guess
130
+ // Not quite there yet, make a second try on guessing the local time, adjust by the offset indicated by the previous guess
94
131
  // Try recreating input time again
95
- // Then calculate and check offset again
96
- const
97
- guessedLocalDate2 = new Date(inputDate.getTime() + offset - guessedInputDateOffset),
98
- guessedInputDate2 = new Date(guessedLocalDate2.toLocaleString("sv-SE", {timeZone: tzString})),
99
- guessedInputDateOffset2 = guessedInputDate2.getTime() - inputDate.getTime();
100
- if (guessedInputDateOffset2 === 0) {
132
+ // Then calculate and check the offset again
133
+ const
134
+ guessedLocalDate2 = new Date(inputDate.getTime() - guessedInputDateOffset),
135
+ guessedInputDateOffset2 = getTimezoneOffset(timePoint.timezone, guessedLocalDate2);
136
+ if ((guessedInputDateOffset2 - guessedInputDateOffset) === 0) {
101
137
  // All good, return local time
102
138
  return guessedLocalDate2;
103
139
  } else if (!throwOnInvalidTime) {
104
- // Input time is invalid, it is probably a point in time skipped by a DST switch, return the local time adjusted by initial offset
140
+ // This guess wasn't spot on either, we're most probably dealing with a DST transition
141
+ // - return the local time adjusted by _initial_ offset
105
142
  return guessedLocalDate;
106
143
  } else {
107
144
  // Input time is invalid, and the library is instructed to throw, so let's do it
108
145
  throw new Error("Invalid date passed to fromTZ()");
109
146
  }
110
147
  }
148
+ };
111
149
 
150
+ /**
151
+ * Converts a date to a specific time zone and returns an object containing year, month,
152
+ * day, hour, (...) and timezone used for the conversion
153
+ *
154
+ * **Please note**: If you just want to _display_ date/time in another
155
+ * time zone, use vanilla JS. See the example below.
156
+ *
157
+ * @public
158
+ * @static
159
+ *
160
+ * @param {date} date - Input date
161
+ * @param {string} [tzString] - Timezone string in Europe/Stockholm format
162
+ *
163
+ * @returns {TimePoint}
164
+ *
165
+ * @example <caption>Example using minitz:</caption>
166
+ * let normalDate = new Date(); // d is a normal Date instance, with local timezone and correct utc representation
167
+ *
168
+ * tzDate = minitz.toTZ(d, 'America/New_York');
169
+ *
170
+ * // Will result in the following object:
171
+ * // {
172
+ * // year: 2022,
173
+ * // month: 9,
174
+ * // day: 28,
175
+ * // hour: 13,
176
+ * // minute: 28,
177
+ * // second: 28,
178
+ * // timezone: "America/New_York"
179
+ * // }
180
+ *
181
+ * @example <caption>Example using vanilla js:</caption>
182
+ * console.log(
183
+ * // Display current time in America/New_York, using sv-SE locale
184
+ * new Date().toLocaleTimeString("sv-SE", { timeZone: "America/New_York" }),
185
+ * );
186
+ *
187
+ */
188
+ minitz.toTZ = function (date, tzString) {
189
+ const target = new Date(date.toLocaleString("sv-SE", {timeZone: tzString}));
190
+ return {
191
+ year: target.getFullYear(),
192
+ month: target.getMonth() + 1,
193
+ day: target.getDate(),
194
+ hour: target.getHours(),
195
+ minute: target.getMinutes(),
196
+ second: target.getSeconds(),
197
+ timezone: tzString
198
+ };
112
199
  };
113
-
200
+
201
+ /**
202
+ * Convenience function which returns a TimePoint object for later use in fromTZ
203
+ *
204
+ * @public
205
+ * @static
206
+ *
207
+ * @param {Number} year - 1970--
208
+ * @param {Number} month - 1-12
209
+ * @param {Number} day - 1-31
210
+ * @param {Number} hour - 0-24
211
+ * @param {Number} minute - 0-60
212
+ * @param {Number} second - 0-60
213
+ * @param {string} timezone - Time zone in format 'Europe/Stockholm'
214
+ *
215
+ * @returns {TimePoint}
216
+ *
217
+ */
218
+ minitz.tp = (y,m,d,h,i,s,t) => { return { year: y, month: m, day: d, hour: h, minute: i, second: s, timezone: t }; };
219
+
220
+ /**
221
+ * Helper function that returns the current UTC offset (in ms) for a specific timezone at a specific point in time
222
+ *
223
+ * @private
224
+ *
225
+ * @param {timeZone} string - Target time zone in IANA database format 'Europe/Stockholm'
226
+ * @param {date} [date] - Point in time to use as base for offset calculation
227
+ *
228
+ * @returns {number} - Offset in ms between UTC and timeZone
229
+ */
230
+ function getTimezoneOffset(timeZone, date = new Date()) {
231
+ const tz = date.toLocaleString("en", {timeZone, timeStyle: "long"}).split(" ").slice(-1)[0];
232
+ const dateString = date.toString();
233
+ return Date.parse(`${dateString} UTC`) - Date.parse(`${dateString} ${tz}`);
234
+ }
235
+
236
+
237
+ /**
238
+ * Helper function that takes a ISO8001 local date time string and creates a Date object.
239
+ * Throws on failure. Throws on invalid date or time.
240
+ *
241
+ * @private
242
+ *
243
+ * @param {string} dateTimeString - an ISO 8601 format date and time string
244
+ * with all components, e.g. 2015-11-24T19:40:00
245
+ * @returns {TimePoint} - TimePoint instance from parsing the string
246
+ */
247
+ function parseISOLocal(dateTimeString, timezone) {
248
+ const dateTimeStringSplit = dateTimeString.split(/\D/);
249
+
250
+ // Check for completeness
251
+ if (dateTimeStringSplit.length < 6) {
252
+ throw new Error("minitz: Incomplete ISO8601 passed to parser.");
253
+ }
254
+
255
+ const
256
+ year = parseInt(dateTimeStringSplit[0], 10),
257
+ month = parseInt(dateTimeStringSplit[1], 10),
258
+ day = parseInt(dateTimeStringSplit[2], 10),
259
+ hour = parseInt(dateTimeStringSplit[3], 10),
260
+ minute = parseInt(dateTimeStringSplit[4], 10),
261
+ second = parseInt(dateTimeStringSplit[5], 10);
262
+
263
+ // Check parts for numeric
264
+ if( isNaN(year) || isNaN(month) || isNaN(day) || isNaN(hour) || isNaN(minute) || isNaN(second) ) {
265
+ throw new Error("minitz: Could not parse ISO8601 string.");
266
+ } else {
267
+ // Check generated date
268
+ const generatedDate = new Date(Date.UTC(year, month-1, day, hour, minute, second));
269
+ if (!(year == generatedDate.getUTCFullYear()
270
+ && month == generatedDate.getUTCMonth()+1
271
+ && day == generatedDate.getUTCDate()
272
+ && hour == generatedDate.getUTCHours()
273
+ && minute == generatedDate.getUTCMinutes()
274
+ && second == generatedDate.getUTCSeconds())) {
275
+ throw new Error("minitz: ISO8601 string contains invalid date or time");
276
+ }
277
+ // Check for UTC flag
278
+ if ((dateTimeString.indexOf("Z") > 0)) {
279
+ // Handle date as UTC time, ignoring input timezone
280
+ return minitz.tp(year, month, day, hour, minute, second, "Etc/UTC");
281
+ } else {
282
+ // Handle date as local time, and convert from specified time zone
283
+ // Note: Date already validated by the UTC-parsing
284
+ return minitz.tp(year, month, day, hour, minute, second, timezone);
285
+ }
286
+ }
287
+ }
288
+
114
289
  minitz.minitz = minitz;
115
290
 
116
291
  /**
@@ -123,7 +298,7 @@
123
298
  * @property {string | Date} [startAt] - When to start running
124
299
  * @property {string | Date} [stopAt] - When to stop running
125
300
  * @property {string} [timezone] - Time zone in Europe/Stockholm format
126
- * @property {boolean} [legacyMode] - Combine day-of-month and day-of-week using OR. Default is AND.
301
+ * @property {boolean} [legacyMode] - Combine day-of-month and day-of-week using true = OR, false = AND. Default is OR.
127
302
  * @property {?} [context] - Used to pass any object to scheduled function
128
303
  */
129
304
 
@@ -142,7 +317,7 @@
142
317
  }
143
318
 
144
319
  // Keep options, or set defaults
145
- options.legacyMode = (options.legacyMode === void 0) ? false : options.legacyMode;
320
+ options.legacyMode = (options.legacyMode === void 0) ? true : options.legacyMode;
146
321
  options.paused = (options.paused === void 0) ? false : options.paused;
147
322
  options.maxRuns = (options.maxRuns === void 0) ? Infinity : options.maxRuns;
148
323
  options.catch = (options.catch === void 0) ? false : options.catch;
@@ -203,21 +378,19 @@
203
378
  * Sets internals using a Date
204
379
  * @private
205
380
  *
206
- * @param {Date} date - Input date
381
+ * @param {Date} date - Input date in local time
207
382
  */
208
- CronDate.prototype.fromDate = function (date) {
383
+ CronDate.prototype.fromDate = function (inputDate) {
209
384
 
210
- if (this.timezone) {
211
- date = minitz.toTZ(date, this.timezone);
212
- }
213
-
214
- this.milliseconds = date.getMilliseconds();
215
- this.seconds = date.getSeconds();
216
- this.minutes = date.getMinutes();
217
- this.hours = date.getHours();
218
- this.days = date.getDate();
219
- this.months = date.getMonth();
220
- this.years = date.getFullYear();
385
+ const date = minitz.toTZ(inputDate, this.timezone);
386
+
387
+ this.milliseconds = inputDate.getMilliseconds();
388
+ this.seconds = date.second;
389
+ this.minutes = date.minute;
390
+ this.hours = date.hour;
391
+ this.days = date.day;
392
+ this.months = date.month - 1;
393
+ this.years = date.year;
221
394
 
222
395
  };
223
396
 
@@ -245,15 +418,15 @@
245
418
  * @param {Date} date - Input date
246
419
  */
247
420
  CronDate.prototype.apply = function () {
248
- const newDate = new Date(this.years, this.months, this.days, this.hours, this.minutes, this.seconds, this.milliseconds);
421
+ const newDate = new Date(Date.UTC(this.years, this.months, this.days, this.hours, this.minutes, this.seconds, this.milliseconds));
249
422
 
250
- this.milliseconds = newDate.getMilliseconds();
251
- this.seconds = newDate.getSeconds();
252
- this.minutes = newDate.getMinutes();
253
- this.hours = newDate.getHours();
254
- this.days = newDate.getDate();
255
- this.months = newDate.getMonth();
256
- this.years = newDate.getFullYear();
423
+ this.milliseconds = newDate.getUTCMilliseconds();
424
+ this.seconds = newDate.getUTCSeconds();
425
+ this.minutes = newDate.getUTCMinutes();
426
+ this.hours = newDate.getUTCHours();
427
+ this.days = newDate.getUTCDate();
428
+ this.months = newDate.getUTCMonth();
429
+ this.years = newDate.getUTCFullYear();
257
430
  };
258
431
 
259
432
  /**
@@ -263,15 +436,7 @@
263
436
  * @param {Date} date - Input date
264
437
  */
265
438
  CronDate.prototype.fromString = function (str) {
266
-
267
- const parsedDate = this.parseISOLocal(str);
268
-
269
- // Throw if we did get an invalid date
270
- if( isNaN(parsedDate) ) {
271
- throw new TypeError("CronDate: Provided string value for CronDate could not be parsed as date.");
272
- }
273
-
274
- this.fromDate(parsedDate);
439
+ return this.fromDate(minitz.fromTZISO(str, this.timezone));
275
440
  };
276
441
 
277
442
  /**
@@ -451,11 +616,10 @@
451
616
  * @returns {Date}
452
617
  */
453
618
  CronDate.prototype.getDate = function (internal) {
454
- const targetDate = new Date(this.years, this.months, this.days, this.hours, this.minutes, this.seconds, this.milliseconds);
455
619
  if (internal || !this.timezone) {
456
- return targetDate;
620
+ return new Date(this.years, this.months, this.days, this.hours, this.minutes, this.seconds, this.milliseconds);
457
621
  } else {
458
- return minitz.fromTZ(targetDate, this.timezone);
622
+ return minitz(this.years, this.months+1, this.days, this.hours, this.minutes, this.seconds, this.timezone);
459
623
  }
460
624
  };
461
625
 
@@ -463,78 +627,10 @@
463
627
  * Convert current state back to a javascript Date() and return UTC milliseconds
464
628
  * @public
465
629
  *
466
- * @param {boolean} internal - If this is an internal call
467
630
  * @returns {Date}
468
631
  */
469
- CronDate.prototype.getTime = function (internal) {
470
- return this.getDate(internal).getTime();
471
- };
472
-
473
- /**
474
- * Takes a iso 8001 local date time string and creates a Date object
475
- * @private
476
- *
477
- * @param {string} dateTimeString - an ISO 8001 format date and time string
478
- * with all components, e.g. 2015-11-24T19:40:00
479
- * @returns {Date|number} - Date instance from parsing the string. May be NaN.
480
- */
481
- CronDate.prototype.parseISOLocal = function (dateTimeString) {
482
- const dateTimeStringSplit = dateTimeString.split(/\D/);
483
-
484
- // Check for completeness
485
- if (dateTimeStringSplit.length < 6) {
486
- return NaN;
487
- }
488
-
489
- const
490
- year = parseInt(dateTimeStringSplit[0], 10),
491
- month = parseInt(dateTimeStringSplit[1], 10),
492
- day = parseInt(dateTimeStringSplit[2], 10),
493
- hour = parseInt(dateTimeStringSplit[3], 10),
494
- minute = parseInt(dateTimeStringSplit[4], 10),
495
- second = parseInt(dateTimeStringSplit[5], 10);
496
-
497
- // Check parts for numeric
498
- if( isNaN(year) || isNaN(month) || isNaN(day) || isNaN(hour) || isNaN(minute) || isNaN(second) ) {
499
- return NaN;
500
- } else {
501
- let generatedDate;
502
-
503
- // Check for UTC flag
504
- if ((dateTimeString.indexOf("Z") > 0)) {
505
-
506
- // Handle date as UTC
507
- generatedDate = new Date(Date.UTC(year, month-1, day, hour, minute, second));
508
-
509
- // Check generated date
510
- if (year == generatedDate.getUTCFullYear()
511
- && month == generatedDate.getUTCMonth()+1
512
- && day == generatedDate.getUTCDate()
513
- && hour == generatedDate.getUTCHours()
514
- && minute == generatedDate.getUTCMinutes()
515
- && second == generatedDate.getUTCSeconds()) {
516
- return generatedDate;
517
- } else {
518
- return NaN;
519
- }
520
- } else {
521
-
522
- // Handle date as local time
523
- generatedDate = new Date(year, month-1, day, hour, minute, second);
524
-
525
- // Check generated date
526
- if (year == generatedDate.getFullYear()
527
- && month == generatedDate.getMonth()+1
528
- && day == generatedDate.getDate()
529
- && hour == generatedDate.getHours()
530
- && minute == generatedDate.getMinutes()
531
- && second == generatedDate.getSeconds()) {
532
- return generatedDate;
533
- } else {
534
- return NaN;
535
- }
536
- }
537
- }
632
+ CronDate.prototype.getTime = function () {
633
+ return this.getDate().getTime();
538
634
  };
539
635
 
540
636
  /**
@@ -1201,9 +1297,9 @@
1201
1297
 
1202
1298
  // Ensure previous run is a CronDate
1203
1299
  prev = new CronDate(prev, this.options.timezone);
1204
-
1300
+
1205
1301
  // Previous run should never be before startAt
1206
- if( this.options.startAt && prev && prev.getTime(true) < this.options.startAt.getTime(true) ) {
1302
+ if( this.options.startAt && prev && prev.getTime() < this.options.startAt.getTime() ) {
1207
1303
  prev = this.options.startAt;
1208
1304
  }
1209
1305
 
@@ -1211,13 +1307,13 @@
1211
1307
  const
1212
1308
  nextRun = this.once || new CronDate(prev, this.options.timezone).increment(this.pattern, this.options, hasPreviousRun);
1213
1309
 
1214
- if (this.once && this.once.getTime(true) <= prev.getTime(true)) {
1310
+ if (this.once && this.once.getTime() <= prev.getTime()) {
1215
1311
  return null;
1216
1312
 
1217
1313
  } else if ((nextRun === null) ||
1218
1314
  (this.options.maxRuns <= 0) ||
1219
1315
  (this.options.kill) ||
1220
- (this.options.stopAt && nextRun.getTime(true) >= this.options.stopAt.getTime(true) )) {
1316
+ (this.options.stopAt && nextRun.getTime() >= this.options.stopAt.getTime() )) {
1221
1317
  return null;
1222
1318
 
1223
1319
  } else {