@terascope/core-utils 2.0.0-dev.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +17 -0
  3. package/dist/src/arrays.d.ts +59 -0
  4. package/dist/src/arrays.d.ts.map +1 -0
  5. package/dist/src/arrays.js +180 -0
  6. package/dist/src/arrays.js.map +1 -0
  7. package/dist/src/big-lru-map.d.ts +14 -0
  8. package/dist/src/big-lru-map.d.ts.map +1 -0
  9. package/dist/src/big-lru-map.js +20 -0
  10. package/dist/src/big-lru-map.js.map +1 -0
  11. package/dist/src/big-map.d.ts +28 -0
  12. package/dist/src/big-map.d.ts.map +1 -0
  13. package/dist/src/big-map.js +148 -0
  14. package/dist/src/big-map.js.map +1 -0
  15. package/dist/src/big-set.d.ts +20 -0
  16. package/dist/src/big-set.d.ts.map +1 -0
  17. package/dist/src/big-set.js +109 -0
  18. package/dist/src/big-set.js.map +1 -0
  19. package/dist/src/booleans.d.ts +44 -0
  20. package/dist/src/booleans.d.ts.map +1 -0
  21. package/dist/src/booleans.js +81 -0
  22. package/dist/src/booleans.js.map +1 -0
  23. package/dist/src/buffers.d.ts +9 -0
  24. package/dist/src/buffers.d.ts.map +1 -0
  25. package/dist/src/buffers.js +22 -0
  26. package/dist/src/buffers.js.map +1 -0
  27. package/dist/src/collector.d.ts +48 -0
  28. package/dist/src/collector.d.ts.map +1 -0
  29. package/dist/src/collector.js +74 -0
  30. package/dist/src/collector.js.map +1 -0
  31. package/dist/src/dates.d.ts +180 -0
  32. package/dist/src/dates.d.ts.map +1 -0
  33. package/dist/src/dates.js +744 -0
  34. package/dist/src/dates.js.map +1 -0
  35. package/dist/src/decorators.d.ts +7 -0
  36. package/dist/src/decorators.d.ts.map +1 -0
  37. package/dist/src/decorators.js +21 -0
  38. package/dist/src/decorators.js.map +1 -0
  39. package/dist/src/deps.d.ts +25 -0
  40. package/dist/src/deps.d.ts.map +1 -0
  41. package/dist/src/deps.js +96 -0
  42. package/dist/src/deps.js.map +1 -0
  43. package/dist/src/empty.d.ts +11 -0
  44. package/dist/src/empty.d.ts.map +1 -0
  45. package/dist/src/empty.js +32 -0
  46. package/dist/src/empty.js.map +1 -0
  47. package/dist/src/entities/data-entity.d.ts +153 -0
  48. package/dist/src/entities/data-entity.d.ts.map +1 -0
  49. package/dist/src/entities/data-entity.js +354 -0
  50. package/dist/src/entities/data-entity.js.map +1 -0
  51. package/dist/src/entities/index.d.ts +3 -0
  52. package/dist/src/entities/index.d.ts.map +1 -0
  53. package/dist/src/entities/index.js +3 -0
  54. package/dist/src/entities/index.js.map +1 -0
  55. package/dist/src/entities/interfaces.d.ts +52 -0
  56. package/dist/src/entities/interfaces.d.ts.map +1 -0
  57. package/dist/src/entities/interfaces.js +13 -0
  58. package/dist/src/entities/interfaces.js.map +1 -0
  59. package/dist/src/entities/utils.d.ts +9 -0
  60. package/dist/src/entities/utils.d.ts.map +1 -0
  61. package/dist/src/entities/utils.js +44 -0
  62. package/dist/src/entities/utils.js.map +1 -0
  63. package/dist/src/env.d.ts +6 -0
  64. package/dist/src/env.d.ts.map +1 -0
  65. package/dist/src/env.js +15 -0
  66. package/dist/src/env.js.map +1 -0
  67. package/dist/src/equality.d.ts +72 -0
  68. package/dist/src/equality.d.ts.map +1 -0
  69. package/dist/src/equality.js +128 -0
  70. package/dist/src/equality.js.map +1 -0
  71. package/dist/src/errors.d.ts +140 -0
  72. package/dist/src/errors.d.ts.map +1 -0
  73. package/dist/src/errors.js +372 -0
  74. package/dist/src/errors.js.map +1 -0
  75. package/dist/src/event-loop.d.ts +33 -0
  76. package/dist/src/event-loop.d.ts.map +1 -0
  77. package/dist/src/event-loop.js +74 -0
  78. package/dist/src/event-loop.js.map +1 -0
  79. package/dist/src/fp.d.ts +15 -0
  80. package/dist/src/fp.d.ts.map +1 -0
  81. package/dist/src/fp.js +25 -0
  82. package/dist/src/fp.js.map +1 -0
  83. package/dist/src/functions.d.ts +19 -0
  84. package/dist/src/functions.d.ts.map +1 -0
  85. package/dist/src/functions.js +58 -0
  86. package/dist/src/functions.js.map +1 -0
  87. package/dist/src/index.d.ts +33 -0
  88. package/dist/src/index.d.ts.map +1 -0
  89. package/dist/src/index.js +33 -0
  90. package/dist/src/index.js.map +1 -0
  91. package/dist/src/iterators.d.ts +9 -0
  92. package/dist/src/iterators.d.ts.map +1 -0
  93. package/dist/src/iterators.js +13 -0
  94. package/dist/src/iterators.js.map +1 -0
  95. package/dist/src/json.d.ts +8 -0
  96. package/dist/src/json.d.ts.map +1 -0
  97. package/dist/src/json.js +46 -0
  98. package/dist/src/json.js.map +1 -0
  99. package/dist/src/logger.d.ts +18 -0
  100. package/dist/src/logger.d.ts.map +1 -0
  101. package/dist/src/logger.js +87 -0
  102. package/dist/src/logger.js.map +1 -0
  103. package/dist/src/numbers.d.ts +86 -0
  104. package/dist/src/numbers.d.ts.map +1 -0
  105. package/dist/src/numbers.js +354 -0
  106. package/dist/src/numbers.js.map +1 -0
  107. package/dist/src/objects.d.ts +66 -0
  108. package/dist/src/objects.d.ts.map +1 -0
  109. package/dist/src/objects.js +170 -0
  110. package/dist/src/objects.js.map +1 -0
  111. package/dist/src/phone-number.d.ts +4 -0
  112. package/dist/src/phone-number.d.ts.map +1 -0
  113. package/dist/src/phone-number.js +31 -0
  114. package/dist/src/phone-number.js.map +1 -0
  115. package/dist/src/promises.d.ts +102 -0
  116. package/dist/src/promises.d.ts.map +1 -0
  117. package/dist/src/promises.js +289 -0
  118. package/dist/src/promises.js.map +1 -0
  119. package/dist/src/queue/index.d.ts +27 -0
  120. package/dist/src/queue/index.d.ts.map +1 -0
  121. package/dist/src/queue/index.js +170 -0
  122. package/dist/src/queue/index.js.map +1 -0
  123. package/dist/src/queue/node.d.ts +7 -0
  124. package/dist/src/queue/node.d.ts.map +1 -0
  125. package/dist/src/queue/node.js +17 -0
  126. package/dist/src/queue/node.js.map +1 -0
  127. package/dist/src/regex.d.ts +19 -0
  128. package/dist/src/regex.d.ts.map +1 -0
  129. package/dist/src/regex.js +138 -0
  130. package/dist/src/regex.js.map +1 -0
  131. package/dist/src/schemas.d.ts +69 -0
  132. package/dist/src/schemas.d.ts.map +1 -0
  133. package/dist/src/schemas.js +619 -0
  134. package/dist/src/schemas.js.map +1 -0
  135. package/dist/src/status-codes.d.ts +67 -0
  136. package/dist/src/status-codes.d.ts.map +1 -0
  137. package/dist/src/status-codes.js +66 -0
  138. package/dist/src/status-codes.js.map +1 -0
  139. package/dist/src/strings.d.ts +279 -0
  140. package/dist/src/strings.d.ts.map +1 -0
  141. package/dist/src/strings.js +578 -0
  142. package/dist/src/strings.js.map +1 -0
  143. package/dist/src/vector.d.ts +2 -0
  144. package/dist/src/vector.d.ts.map +1 -0
  145. package/dist/src/vector.js +16 -0
  146. package/dist/src/vector.js.map +1 -0
  147. package/package.json +72 -0
@@ -0,0 +1,744 @@
1
+ import validator from 'validator';
2
+ import parser from 'datemath-parser';
3
+ import { parse as parseDate, format as formatDate, differenceInMilliseconds, differenceInSeconds, differenceInMinutes, differenceInHours, differenceInDays, differenceInCalendarDays, differenceInBusinessDays, differenceInWeeks, differenceInCalendarISOWeeks, differenceInCalendarISOWeekYears, differenceInMonths, differenceInCalendarMonths, differenceInQuarters, differenceInCalendarQuarters, differenceInYears, differenceInCalendarYears, differenceInISOWeekYears, intervalToDuration, formatISODuration, isFuture as _isFuture, isPast as _isPast, isLeapYear as _isLeapYear, isToday as _isToday, isTomorrow as _isTomorrow, isYesterday as _isYesterday, add, sub, isBefore as _isBefore, isAfter as _isAfter, } from 'date-fns';
4
+ import { DateFormat, ISO8601DateSegment } from '@terascope/types';
5
+ import { getTimezoneOffset as tzOffset } from 'date-fns-tz';
6
+ import { isString } from './strings.js';
7
+ import { isNumber, toInteger, isInteger, inNumberRange, bigIntToJSON } from './numbers.js';
8
+ import { isBoolean } from './booleans.js';
9
+ import { getTypeOf } from './deps.js';
10
+ // date-fns doesn't handle utc correctly here
11
+ // https://github.com/date-fns/date-fns/issues/376
12
+ // https://github.com/date-fns/date-fns/blob/d0efa9eae1cf05c0e27461296b537b9dd46283d4/src/format/index.js#L399-L403
13
+ export const timezoneOffset = new Date().getTimezoneOffset() * 60_000;
14
+ /**
15
+ * A helper function for making an ISODate string
16
+ */
17
+ export function makeISODate(value) {
18
+ if (value == null)
19
+ return new Date().toISOString();
20
+ const date = getValidDate(value);
21
+ if (date === false) {
22
+ throw new Error(`Invalid date ${date}`);
23
+ }
24
+ return date.toISOString();
25
+ }
26
+ /** A simplified implementation of moment(new Date(val)).isValid() */
27
+ export function isValidDate(val) {
28
+ return _getValidDate(val) !== false;
29
+ }
30
+ /**
31
+ * Coerces value into a valid date, returns false if it is invalid
32
+ */
33
+ function _getValidDate(val) {
34
+ // this is our hot path since this is how commonly store this
35
+ if (typeof val === 'number') {
36
+ if (!Number.isInteger(val))
37
+ return false;
38
+ return new Date(val);
39
+ }
40
+ if (val == null || isBoolean(val))
41
+ return false;
42
+ if (val instanceof Date) {
43
+ if (!isValidDateInstance(val)) {
44
+ return false;
45
+ }
46
+ return val;
47
+ }
48
+ if (typeof val === 'bigint') {
49
+ // eslint-disable-next-line no-param-reassign
50
+ val = bigIntToJSON(val);
51
+ if (typeof val === 'string')
52
+ return false;
53
+ }
54
+ if (isDateTuple(val))
55
+ return new Date(val[0]);
56
+ const d = new Date(val);
57
+ if (isValidDateInstance(d))
58
+ return d;
59
+ // safari needs slashes when in month-date-year format
60
+ // don't call _getValidDate - could cause infinite loop
61
+ if (typeof val === 'string') {
62
+ const dashesToSlashes = new Date(val.replace(/-/g, '/'));
63
+ if (isValidDateInstance(dashesToSlashes)) {
64
+ return dashesToSlashes;
65
+ }
66
+ }
67
+ return false;
68
+ }
69
+ /**
70
+ * Coerces value into a valid date, returns false if it is invalid.
71
+ * Has added support for converting from date math (i.e. now+1h, now-1m, now+2d/y, 2021-01-01||+2d)
72
+ */
73
+ export function getValidDate(val, relativeNow = new Date()) {
74
+ const validDate = _getValidDate(val);
75
+ if (validDate)
76
+ return validDate;
77
+ if (!relativeNow)
78
+ return false;
79
+ return parseRelativeDate(val, relativeNow);
80
+ }
81
+ /**
82
+ * tries to date math values to dates
83
+ */
84
+ function parseRelativeDate(input, now) {
85
+ if (!input || typeof input !== 'string')
86
+ return false;
87
+ // remove any spaces and ensure lowercase 'now' (keep all others normal case)
88
+ const trimmed = input.replace(/\s/g, '').replace(/(n|N)(o|O)(w|W)/g, 'now');
89
+ const dateMath = parseDateMath(trimmed, now);
90
+ if (dateMath)
91
+ return dateMath;
92
+ return false;
93
+ }
94
+ /**
95
+ * tries to parse date math (i.e. now+1h, now-1m) to a date
96
+ */
97
+ function parseDateMath(value, now) {
98
+ try {
99
+ return _getValidDate(new Date(parser.parse(value, now)));
100
+ }
101
+ catch (err) {
102
+ return false;
103
+ }
104
+ }
105
+ /**
106
+ * Returns a valid date or throws, {@see getValidDate}
107
+ */
108
+ export function getValidDateOrThrow(val) {
109
+ const date = getValidDate(val);
110
+ if (date === false) {
111
+ throw new TypeError(`Expected ${val} (${getTypeOf(val)}) to be in a standard date format`);
112
+ }
113
+ return date;
114
+ }
115
+ export function toTimeZone(val, timezone) {
116
+ if (!isString(timezone)) {
117
+ throw new Error(`Invalid argument timezone, it must be a string, got ${getTypeOf(timezone)}`);
118
+ }
119
+ const date = getValidDateOrThrow(val);
120
+ const offset = getTimezoneOffset(date, timezone);
121
+ // this should only fail right now in node v16, not v18
122
+ // as some timezones are not available in v16
123
+ if (isNaN(offset))
124
+ return null;
125
+ return setTimezone(date, offset);
126
+ }
127
+ /**
128
+ * @returns date object from date tuple
129
+ */
130
+ function _dateTupleToDateObject(val, getUTC = false) {
131
+ if (getUTC) {
132
+ return new Date(val[0]);
133
+ }
134
+ return new Date(val[0] + (val[1] * 60_000));
135
+ }
136
+ /**
137
+ * Returns a valid date with the timezone applied or throws{@see getValidDate}
138
+ */
139
+ export function getValidDateWithTimezoneOrThrow(val, getUTC = false) {
140
+ if (isDateTuple(val)) {
141
+ return _dateTupleToDateObject(val, getUTC);
142
+ }
143
+ // we don't pass getUTC here as this function ignores dateTuple timezone offsets for now
144
+ return getValidDateOrThrow(val);
145
+ }
146
+ /**
147
+ * Returns a valid date with the timezone applied {@see getValidDate}
148
+ */
149
+ export function getValidDateWithTimezone(val, getUTC = false) {
150
+ if (isDateTuple(val)) {
151
+ return _dateTupleToDateObject(val, getUTC);
152
+ }
153
+ return getValidDate(val);
154
+ }
155
+ /**
156
+ * Returns a valid date or throws, {@see getValidDate}
157
+ */
158
+ export function getValidDateOrNumberOrThrow(val) {
159
+ if (typeof val === 'number' && !Number.isInteger(val))
160
+ return val;
161
+ if (isDateTuple(val))
162
+ return val[0];
163
+ const date = getValidDate(val);
164
+ if (date === false) {
165
+ throw new TypeError(`Expected ${val} (${getTypeOf(val)}) to be in a standard date format`);
166
+ }
167
+ return date;
168
+ }
169
+ export function isValidDateInstance(val) {
170
+ // this has to use isNaN not Number.isNaN
171
+ return val instanceof Date && !isNaN(val);
172
+ }
173
+ /** Ensure unix time */
174
+ export function getTime(val) {
175
+ if (val == null)
176
+ return Date.now();
177
+ const result = getValidDate(val);
178
+ if (result === false)
179
+ return false;
180
+ return result.getTime();
181
+ }
182
+ export function getUnixTime(val) {
183
+ const time = getTime(val);
184
+ if (time !== false)
185
+ return Math.floor(time / 1000);
186
+ return time;
187
+ }
188
+ /**
189
+ * Checks to see if an input is a unix time
190
+ */
191
+ export function isUnixTime(input, allowBefore1970 = true) {
192
+ const value = toInteger(input);
193
+ if (value === false)
194
+ return false;
195
+ if (allowBefore1970)
196
+ return true;
197
+ return value >= 0;
198
+ }
199
+ /**
200
+ * A functional version of isUnixTime
201
+ */
202
+ export function isUnixTimeFP(allowBefore1970) {
203
+ return function _isUnixTime(input) {
204
+ return isUnixTime(input, allowBefore1970);
205
+ };
206
+ }
207
+ /**
208
+ * Checks to see if an input is a ISO 8601 date
209
+ */
210
+ export function isISO8601(input) {
211
+ if (!isString(input))
212
+ return false;
213
+ return validator.isISO8601(input);
214
+ }
215
+ /**
216
+ * Convert a value to an ISO 8601 date string.
217
+ * This should be used over makeISODate
218
+ */
219
+ export function toISO8601(value) {
220
+ if (isNumber(value)) {
221
+ return new Date(value).toISOString();
222
+ }
223
+ if (isDateTuple(value)) {
224
+ // this is utc so just fall back to
225
+ // to the correct timezone
226
+ if (value[1] === 0) {
227
+ return new Date(value[0]).toISOString();
228
+ }
229
+ // anytime we have a date tuple, manifest it in local time not UTC
230
+ const localTime = value[0] + (value[1] * 60_000);
231
+ return new Date(localTime).toISOString()
232
+ .replace('Z', _genISOTimezone(value[1]));
233
+ }
234
+ return makeISODate(value);
235
+ }
236
+ /**
237
+ * Generate the ISO8601
238
+ */
239
+ function _genISOTimezone(offset) {
240
+ const absOffset = Math.abs(offset);
241
+ const hours = Math.floor(absOffset / 60);
242
+ const minutes = absOffset - (hours * 60);
243
+ const sign = offset < 0 ? '-' : '+';
244
+ return `${sign}${_padNum(hours)}:${_padNum(minutes)}`;
245
+ }
246
+ /**
247
+ * a simple version of pad that only deals with simple cases
248
+ */
249
+ function _padNum(input) {
250
+ return input < 10 ? `0${input}` : `${input}`;
251
+ }
252
+ /**
253
+ * Set the timezone offset of a date, returns a date tuple
254
+ */
255
+ export function setTimezone(input, timezone) {
256
+ const validTZ = isNumber(timezone) ? timezone : timezoneToOffset(timezone);
257
+ return _makeDateTuple(input, validTZ);
258
+ }
259
+ /**
260
+ * A curried version of setTimezone
261
+ */
262
+ export function setTimezoneFP(timezone) {
263
+ const validTZ = isNumber(timezone) ? timezone : timezoneToOffset(timezone);
264
+ return function _setTimezone(input) {
265
+ return _makeDateTuple(input, validTZ);
266
+ };
267
+ }
268
+ function _makeDateTuple(input, offset) {
269
+ if (isNumber(input))
270
+ return [input, offset];
271
+ if (isDateTuple(input))
272
+ return [input[0], offset];
273
+ const date = getValidDateOrThrow(input);
274
+ return [date.getTime(), offset];
275
+ }
276
+ /**
277
+ * Verify if an input is a Date Tuple
278
+ */
279
+ export function isDateTuple(input) {
280
+ return Array.isArray(input)
281
+ && input.length === 2
282
+ && Number.isInteger(input[0])
283
+ && Number.isInteger(input[1])
284
+ // the timezone has to be within 24hours
285
+ // in minutes
286
+ && input[1] <= 1440
287
+ && input[1] >= -1440;
288
+ }
289
+ /**
290
+ * Returns a function to trim the ISO 8601 date segment
291
+ * useful for creating yearly, monthly, daily or hourly dates
292
+ */
293
+ export function trimISODateSegment(segment) {
294
+ return function _trimISODate(input) {
295
+ const date = getValidDateWithTimezoneOrThrow(input, false);
296
+ if (segment === ISO8601DateSegment.hourly) {
297
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), 0, 0, 0)).getTime();
298
+ }
299
+ if (segment === ISO8601DateSegment.daily) {
300
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0, 0)).getTime();
301
+ }
302
+ if (segment === ISO8601DateSegment.monthly) {
303
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 1, 0, 0, 0, 0)).getTime();
304
+ }
305
+ if (segment === ISO8601DateSegment.yearly) {
306
+ return new Date(Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0)).getTime();
307
+ }
308
+ throw new Error(`Invalid segment "${segment}" given`);
309
+ };
310
+ }
311
+ /**
312
+ * track a timeout to see if it expires
313
+ * @returns a function that will returns false if the time elapsed
314
+ */
315
+ export function trackTimeout(timeoutMs) {
316
+ const startTime = Date.now();
317
+ return () => {
318
+ const elapsed = Date.now() - startTime;
319
+ if (timeoutMs > -1 && elapsed > timeoutMs) {
320
+ return elapsed;
321
+ }
322
+ return false;
323
+ };
324
+ }
325
+ /** converts smaller than a week milliseconds to human readable time */
326
+ export function toHumanTime(ms) {
327
+ const ONE_SEC = 1000;
328
+ const ONE_MIN = ONE_SEC * 60;
329
+ const ONE_HOUR = ONE_MIN * 60;
330
+ const ONE_DAY = ONE_HOUR * 24;
331
+ const minOver = 1.5;
332
+ if (ms > ONE_DAY * minOver && ms < ONE_DAY * 7) {
333
+ return `${Math.round((ms * 100) / ONE_DAY) / 100}day`;
334
+ }
335
+ if (ms > ONE_HOUR * minOver)
336
+ return `${Math.round((ms * 100) / ONE_HOUR) / 100}hr`;
337
+ if (ms > ONE_MIN * minOver)
338
+ return `${Math.round((ms * 100) / ONE_MIN) / 100}min`;
339
+ if (ms > ONE_SEC * minOver) {
340
+ return `${Math.round((ms * 100) / ONE_SEC) / 100}sec`;
341
+ }
342
+ if (ms < ONE_SEC * minOver) {
343
+ return `${Math.round(ms)}ms`;
344
+ }
345
+ return `${Math.round((ms * 100) / ONE_DAY) / 100}day`;
346
+ }
347
+ export function parseCustomDateFormat(value, format, referenceDate) {
348
+ if (typeof value !== 'string') {
349
+ throw new Error(`Expected string for formatted date fields, got ${value}`);
350
+ }
351
+ const hasTimezoneFormat = format.match(/[xX]/);
352
+ const date = parseDate(value, format, referenceDate);
353
+ if (!isValidDateInstance(date)) {
354
+ throw new Error(`Expected value ${value} to be a date string with format ${format}`);
355
+ }
356
+ // the format indicates its already UTC conversion
357
+ if (hasTimezoneFormat)
358
+ return date.getTime();
359
+ // need subtract the date offset here to
360
+ // in order to deal with UTC time
361
+ return date.getTime() - timezoneOffset;
362
+ }
363
+ /**
364
+ * Parse a date value (that has already been validated)
365
+ * and return the epoch millis time.
366
+ */
367
+ export function parseDateValue(value, format, referenceDate) {
368
+ if (format === DateFormat.epoch || format === DateFormat.seconds) {
369
+ const int = toInteger(value);
370
+ if (int === false) {
371
+ throw new Error(`Expected value ${value} to be a valid time`);
372
+ }
373
+ return Math.floor(int * 1000);
374
+ }
375
+ if (format && !(format in DateFormat)) {
376
+ return parseCustomDateFormat(value, format, referenceDate);
377
+ }
378
+ const result = getTime(value);
379
+ if (result === false) {
380
+ throw new Error(`Expected value ${value} to be a valid date`);
381
+ }
382
+ return result;
383
+ }
384
+ /**
385
+ * Format the parsed date value
386
+ */
387
+ export function formatDateValue(value, format) {
388
+ const inMs = _toMilliseconds(value);
389
+ if (format === DateFormat.epoch_millis || format === DateFormat.milliseconds) {
390
+ return inMs;
391
+ }
392
+ if (format === DateFormat.epoch || format === DateFormat.seconds) {
393
+ return Math.floor(inMs / 1000);
394
+ }
395
+ if (format && !(format in DateFormat)) {
396
+ const inputValue = format.match(/[xX]/) ? inMs : inMs + timezoneOffset;
397
+ // need add our offset here to
398
+ // deal with UTC time
399
+ return formatDate(inputValue, format);
400
+ }
401
+ return toISO8601(value);
402
+ }
403
+ function _toMilliseconds(value) {
404
+ if (isDateTuple(value))
405
+ return value[0];
406
+ return value instanceof Date ? value.getTime() : value;
407
+ }
408
+ export const getDurationFunc = {
409
+ milliseconds: differenceInMilliseconds,
410
+ seconds: differenceInSeconds,
411
+ minutes: differenceInMinutes,
412
+ hours: differenceInHours,
413
+ days: differenceInDays,
414
+ calendarDays: differenceInCalendarDays,
415
+ businessDays: differenceInBusinessDays,
416
+ weeks: differenceInWeeks,
417
+ calendarWeeks: differenceInCalendarISOWeeks,
418
+ months: differenceInMonths,
419
+ calendarMonths: differenceInCalendarMonths,
420
+ quarters: differenceInQuarters,
421
+ calendarQuarters: differenceInCalendarQuarters,
422
+ years: differenceInYears,
423
+ calendarYears: differenceInCalendarYears,
424
+ calendarISOWeekYears: differenceInCalendarISOWeekYears,
425
+ ISOWeekYears: differenceInISOWeekYears
426
+ };
427
+ export function getTimeBetween(input, args) {
428
+ const { interval } = args;
429
+ const [time1, time2] = _getStartEndTime(input, args);
430
+ const date1 = getValidDateWithTimezoneOrThrow(time1, false);
431
+ const date2 = getValidDateWithTimezoneOrThrow(time2, false);
432
+ if (interval === 'ISO8601') {
433
+ return formatISODuration(intervalToDuration({
434
+ start: date1,
435
+ end: date2
436
+ }));
437
+ }
438
+ return getDurationFunc[interval](date2, date1);
439
+ }
440
+ function _getStartEndTime(input, args) {
441
+ const { start, end } = args;
442
+ if (start == null && end == null) {
443
+ throw Error('Must provide a start or an end argument');
444
+ }
445
+ if (start)
446
+ return [start, input];
447
+ return [input, end];
448
+ }
449
+ /**
450
+ * A functional version of getTimeBetween
451
+ */
452
+ export function getTimeBetweenFP(args) {
453
+ return function _getTimeBetween(input) {
454
+ return getTimeBetween(input, args);
455
+ };
456
+ }
457
+ export function isSunday(input) {
458
+ const date = getValidDateWithTimezone(input, false);
459
+ if (!date)
460
+ return false;
461
+ return date.getDay() === 0;
462
+ }
463
+ export function isMonday(input) {
464
+ const date = getValidDateWithTimezone(input, false);
465
+ if (!date)
466
+ return false;
467
+ return date.getDay() === 1;
468
+ }
469
+ export function isTuesday(input) {
470
+ const date = getValidDateWithTimezone(input, false);
471
+ if (!date)
472
+ return false;
473
+ return date.getDay() === 2;
474
+ }
475
+ export function isWednesday(input) {
476
+ const date = getValidDateWithTimezone(input, false);
477
+ if (!date)
478
+ return false;
479
+ return date.getDay() === 3;
480
+ }
481
+ export function isThursday(input) {
482
+ const date = getValidDateWithTimezone(input, false);
483
+ if (!date)
484
+ return false;
485
+ return date.getDay() === 4;
486
+ }
487
+ export function isFriday(input) {
488
+ const date = getValidDateWithTimezone(input, false);
489
+ if (!date)
490
+ return false;
491
+ return date.getDay() === 5;
492
+ }
493
+ export function isSaturday(input) {
494
+ const date = getValidDateWithTimezone(input, false);
495
+ if (!date)
496
+ return false;
497
+ return date.getDay() === 6;
498
+ }
499
+ export function isWeekday(input) {
500
+ const date = getValidDateWithTimezone(input, false);
501
+ if (!date)
502
+ return false;
503
+ const day = date.getDay();
504
+ return day >= 1 && day <= 5;
505
+ }
506
+ export function isWeekend(input) {
507
+ const date = getValidDateWithTimezone(input, false);
508
+ if (!date)
509
+ return false;
510
+ const day = date.getDay();
511
+ return day === 0 || day === 6;
512
+ }
513
+ export function isFuture(input) {
514
+ const date = getValidDateWithTimezone(input, false);
515
+ if (!date)
516
+ return false;
517
+ return _isFuture(date);
518
+ }
519
+ export function isPast(input) {
520
+ const date = getValidDateWithTimezone(input, false);
521
+ if (!date)
522
+ return false;
523
+ return _isPast(date);
524
+ }
525
+ export function isLeapYear(input) {
526
+ const date = getValidDateWithTimezone(input, false);
527
+ if (!date)
528
+ return false;
529
+ return _isLeapYear(date);
530
+ }
531
+ export function isTomorrow(input) {
532
+ const date = getValidDateWithTimezone(input, false);
533
+ if (!date)
534
+ return false;
535
+ return _isTomorrow(date);
536
+ }
537
+ export function isToday(input) {
538
+ const date = getValidDateWithTimezone(input, false);
539
+ if (!date)
540
+ return false;
541
+ return _isToday(date);
542
+ }
543
+ export function isYesterday(input) {
544
+ const date = getValidDateWithTimezone(input, false);
545
+ if (!date)
546
+ return false;
547
+ return _isYesterday(date);
548
+ }
549
+ export function addToDate(input, args) {
550
+ const date = getValidDateWithTimezoneOrThrow(input, false);
551
+ if ('expr' in args) {
552
+ return parser.parse(`now+${args.expr}`, date);
553
+ }
554
+ return add(date, args).getTime();
555
+ }
556
+ export function addToDateFP(args) {
557
+ return function _addToDateFP(input) {
558
+ return addToDate(input, args);
559
+ };
560
+ }
561
+ export function subtractFromDate(input, args) {
562
+ const date = getValidDateWithTimezoneOrThrow(input, false);
563
+ if ('expr' in args) {
564
+ return parser.parse(`now-${args.expr}`, date);
565
+ }
566
+ return sub(date, args).getTime();
567
+ }
568
+ export function subtractFromDateFP(args) {
569
+ return function _subtractFromDateFP(input) {
570
+ return subtractFromDate(input, args);
571
+ };
572
+ }
573
+ export function isBefore(input, date) {
574
+ const date1 = getValidDateWithTimezone(input, false);
575
+ const date2 = getValidDateWithTimezone(date, false);
576
+ if (date1 && date2) {
577
+ return _isBefore(date1, date2);
578
+ }
579
+ return false;
580
+ }
581
+ export function isAfter(input, date) {
582
+ const date1 = getValidDateWithTimezone(input, false);
583
+ const date2 = getValidDateWithTimezone(date, false);
584
+ if (date1 && date2) {
585
+ return _isAfter(date1, date2);
586
+ }
587
+ return false;
588
+ }
589
+ export function isBetween(input, args) {
590
+ const { start, end } = args;
591
+ const inputDate = getValidDateWithTimezone(input, false);
592
+ const date1 = getValidDateWithTimezone(start, false);
593
+ const date2 = getValidDateWithTimezone(end, false);
594
+ if (inputDate && date1 && date2) {
595
+ return _isAfter(inputDate, date1) && _isBefore(inputDate, date2);
596
+ }
597
+ return false;
598
+ }
599
+ /** Given a timezone, it will return the minutes of its offset from UTC time */
600
+ export function timezoneToOffset(timezone) {
601
+ if (!isString(timezone)) {
602
+ throw new Error(`Invalid argument timezone, it must be a string, got ${getTypeOf(timezone)}`);
603
+ }
604
+ return Math.round(tzOffset(timezone) / (1000 * 60));
605
+ }
606
+ /** Given a date and timezone, it will return the offset from UTC in minutes.
607
+ * This is more accurate than timezoneToOffset as it can better account for day lights saving time
608
+ * */
609
+ export function getTimezoneOffset(input, timezone) {
610
+ const date = getValidDateOrThrow(input);
611
+ if (!isString(timezone)) {
612
+ throw new Error(`Invalid argument timezone, it must be a string, got ${getTypeOf(timezone)}`);
613
+ }
614
+ return Math.round(tzOffset(timezone, date) / (1000 * 60));
615
+ }
616
+ /** Given a timezone, it will return a function that will take in dates that will
617
+ * be converted the offset in minutes. This is more accurate than timezoneToOffset
618
+ * as it can better account for day lights saving time
619
+ * */
620
+ export function getTimezoneOffsetFP(timezone) {
621
+ if (!isString(timezone)) {
622
+ throw new Error(`Invalid argument timezone, it must be a string, got ${getTypeOf(timezone)}`);
623
+ }
624
+ return function _getTimezoneOffsetFP(input) {
625
+ const date = getValidDateOrThrow(input);
626
+ return Math.round(tzOffset(timezone, date) / (1000 * 60));
627
+ };
628
+ }
629
+ export function setMilliseconds(ms) {
630
+ if (!isInteger(ms) || !inNumberRange(ms, { min: 0, max: 999, inclusive: true })) {
631
+ throw Error(`milliseconds value must be an integer between 0 and 999, received ${ms}`);
632
+ }
633
+ return function _setMilliseconds(input) {
634
+ const inputDate = getValidDateOrThrow(input);
635
+ return inputDate.setUTCMilliseconds(ms);
636
+ };
637
+ }
638
+ export function setSeconds(seconds) {
639
+ if (!isInteger(seconds) || !inNumberRange(seconds, { min: 0, max: 59, inclusive: true })) {
640
+ throw Error(`seconds value must be an integer between 0 and 59, received ${seconds}`);
641
+ }
642
+ return function _setSeconds(input) {
643
+ const inputDate = getValidDateOrThrow(input);
644
+ return inputDate.setUTCSeconds(seconds);
645
+ };
646
+ }
647
+ export function setMinutes(minutes) {
648
+ if (!isInteger(minutes) || !inNumberRange(minutes, { min: 0, max: 59, inclusive: true })) {
649
+ throw Error(`minutes value must be an integer between 0 and 59, received ${minutes}`);
650
+ }
651
+ return function _setMinutes(input) {
652
+ const inputDate = getValidDateWithTimezoneOrThrow(input, false);
653
+ return inputDate.setUTCMinutes(minutes);
654
+ };
655
+ }
656
+ export function setHours(hours) {
657
+ if (!isInteger(hours) || !inNumberRange(hours, { min: 0, max: 23, inclusive: true })) {
658
+ throw Error(`hours value must be an integer between 0 and 23, received ${hours}`);
659
+ }
660
+ return function _setHours(input) {
661
+ const inputDate = getValidDateWithTimezoneOrThrow(input, false);
662
+ return inputDate.setUTCHours(hours);
663
+ };
664
+ }
665
+ export function setDate(date) {
666
+ if (!isInteger(date) || !inNumberRange(date, { min: 1, max: 31, inclusive: true })) {
667
+ throw Error(`date value must be an integer between 1 and 31, received ${date}`);
668
+ }
669
+ return function _setDate(input) {
670
+ const inputDate = getValidDateWithTimezoneOrThrow(input, false);
671
+ return inputDate.setUTCDate(date);
672
+ };
673
+ }
674
+ export function setMonth(month) {
675
+ if (!isInteger(month) || !inNumberRange(month, { min: 1, max: 12, inclusive: true })) {
676
+ throw Error(`month value must be an integer between 1 and 12, received ${month}`);
677
+ }
678
+ return function _setMonth(input) {
679
+ const inputDate = getValidDateWithTimezoneOrThrow(input, false);
680
+ return inputDate.setUTCMonth(month - 1);
681
+ };
682
+ }
683
+ export function setYear(year) {
684
+ if (!isInteger(year)) {
685
+ throw Error(`year value must be an integer, received ${year}`);
686
+ }
687
+ return function _setYear(input) {
688
+ const inputDate = getValidDateWithTimezoneOrThrow(input, false);
689
+ return inputDate.setUTCFullYear(year);
690
+ };
691
+ }
692
+ export function getMilliseconds(input) {
693
+ return getValidDateOrThrow(input).getUTCMilliseconds();
694
+ }
695
+ export function getSeconds(input) {
696
+ return getValidDateOrThrow(input).getUTCSeconds();
697
+ }
698
+ export function getUTCMinutes(input) {
699
+ const date = getValidDateWithTimezoneOrThrow(input, true);
700
+ return date.getUTCMinutes();
701
+ }
702
+ export function getMinutes(input) {
703
+ const date = getValidDateWithTimezoneOrThrow(input, false);
704
+ return date.getUTCMinutes();
705
+ }
706
+ export function getUTCHours(input) {
707
+ const date = getValidDateWithTimezoneOrThrow(input, true);
708
+ return date.getUTCHours();
709
+ }
710
+ export function getHours(input) {
711
+ const date = getValidDateWithTimezoneOrThrow(input, false);
712
+ return date.getUTCHours();
713
+ }
714
+ export function getUTCDate(input) {
715
+ const date = getValidDateWithTimezoneOrThrow(input, true);
716
+ return date.getUTCDate();
717
+ }
718
+ export function getDate(input) {
719
+ const date = getValidDateWithTimezoneOrThrow(input, false);
720
+ return date.getUTCDate();
721
+ }
722
+ export function getUTCMonth(input) {
723
+ return getValidDateWithTimezoneOrThrow(input, true).getUTCMonth() + 1;
724
+ }
725
+ export function getMonth(input) {
726
+ return getValidDateWithTimezoneOrThrow(input, false).getUTCMonth() + 1;
727
+ }
728
+ export function getUTCYear(input) {
729
+ return getValidDateWithTimezoneOrThrow(input, true).getUTCFullYear();
730
+ }
731
+ export function getYear(input) {
732
+ return getValidDateWithTimezoneOrThrow(input, false).getUTCFullYear();
733
+ }
734
+ /** Will convert a date to its epoch millisecond format or throw if invalid */
735
+ export function toEpochMSOrThrow(input) {
736
+ if (isDateTuple(input))
737
+ return input;
738
+ const epochMillis = getTime(input);
739
+ if (epochMillis === false) {
740
+ throw new TypeError(`Expected ${input} (${getTypeOf(input)}) to be a standard date value`);
741
+ }
742
+ return epochMillis;
743
+ }
744
+ //# sourceMappingURL=dates.js.map