@naturalcycles/js-lib 14.236.0 → 14.237.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/dist/datetime/localDate.d.ts +2 -1
- package/dist/datetime/localDate.js +7 -0
- package/dist/datetime/localTime.d.ts +67 -26
- package/dist/datetime/localTime.js +99 -33
- package/dist/datetime/wallTime.d.ts +33 -0
- package/dist/datetime/wallTime.js +48 -0
- package/dist/index.d.ts +1 -5
- package/dist/index.js +1 -5
- package/dist-esm/datetime/localDate.js +7 -0
- package/dist-esm/datetime/localTime.js +98 -30
- package/dist-esm/datetime/wallTime.js +44 -0
- package/dist-esm/index.js +1 -5
- package/package.json +1 -1
- package/src/datetime/localDate.ts +9 -1
- package/src/datetime/localTime.ts +110 -37
- package/src/datetime/wallTime.ts +56 -0
- package/src/index.ts +1 -5
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Iterable2 } from '../iter/iterable2';
|
|
2
2
|
import type { Inclusiveness, IsoDateString, IsoDateTimeString, MonthId, SortDirection, UnixTimestampMillisNumber, UnixTimestampNumber } from '../types';
|
|
3
|
-
import { ISODayOfWeek, LocalTime } from './localTime';
|
|
3
|
+
import { DateObject, ISODayOfWeek, LocalTime } from './localTime';
|
|
4
4
|
export type LocalDateUnit = LocalDateUnitStrict | 'week';
|
|
5
5
|
export type LocalDateUnitStrict = 'year' | 'month' | 'day';
|
|
6
6
|
export type LocalDateInput = LocalDate | Date | IsoDateString;
|
|
@@ -103,6 +103,7 @@ export declare class LocalDate {
|
|
|
103
103
|
* Unlike normal `.toDate` that uses browser's timezone by default.
|
|
104
104
|
*/
|
|
105
105
|
toDateInUTC(): Date;
|
|
106
|
+
toDateObject(): DateObject;
|
|
106
107
|
/**
|
|
107
108
|
* Converts LocalDate to LocalTime with 0 hours, 0 minutes, 0 seconds.
|
|
108
109
|
* LocalTime's Date will be in local timezone.
|
|
@@ -323,6 +323,13 @@ class LocalDate {
|
|
|
323
323
|
toDateInUTC() {
|
|
324
324
|
return new Date(this.toISODateTimeInUTC());
|
|
325
325
|
}
|
|
326
|
+
toDateObject() {
|
|
327
|
+
return {
|
|
328
|
+
year: this.$year,
|
|
329
|
+
month: this.$month,
|
|
330
|
+
day: this.$day,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
326
333
|
/**
|
|
327
334
|
* Converts LocalDate to LocalTime with 0 hours, 0 minutes, 0 seconds.
|
|
328
335
|
* LocalTime's Date will be in local timezone.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Inclusiveness, IsoDateString, IsoDateTimeString, MonthId, NumberOfHours, NumberOfMinutes, SortDirection, UnixTimestampMillisNumber, UnixTimestampNumber } from '../types';
|
|
2
2
|
import { LocalDate } from './localDate';
|
|
3
|
+
import { WallTime } from './wallTime';
|
|
3
4
|
export type LocalTimeUnit = 'year' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second';
|
|
4
5
|
export declare enum ISODayOfWeek {
|
|
5
6
|
MONDAY = 1,
|
|
@@ -12,13 +13,13 @@ export declare enum ISODayOfWeek {
|
|
|
12
13
|
}
|
|
13
14
|
export type LocalTimeInput = LocalTime | Date | IsoDateTimeString | UnixTimestampNumber;
|
|
14
15
|
export type LocalTimeFormatter = (ld: LocalTime) => string;
|
|
15
|
-
export type
|
|
16
|
-
interface
|
|
16
|
+
export type DateTimeObject = DateObject & TimeObject;
|
|
17
|
+
export interface DateObject {
|
|
17
18
|
year: number;
|
|
18
19
|
month: number;
|
|
19
20
|
day: number;
|
|
20
21
|
}
|
|
21
|
-
interface
|
|
22
|
+
export interface TimeObject {
|
|
22
23
|
hour: number;
|
|
23
24
|
minute: number;
|
|
24
25
|
second: number;
|
|
@@ -36,6 +37,51 @@ export declare class LocalTime {
|
|
|
36
37
|
* Opposite of `.utc()` method.
|
|
37
38
|
*/
|
|
38
39
|
local(): LocalTime;
|
|
40
|
+
/**
|
|
41
|
+
* Returns [cloned] fake LocalTime that has yyyy-mm-dd hh:mm:ss in the provided timezone.
|
|
42
|
+
* It is a fake LocalTime in a sense that it's timezone is not real.
|
|
43
|
+
* See this ("common errors"): https://stackoverflow.com/a/15171030/4919972
|
|
44
|
+
* Fake also means that unixTimestamp of that new LocalDate is not the same.
|
|
45
|
+
* For that reason we return WallTime, and not a LocalTime.
|
|
46
|
+
* WallTime can be pretty-printed as Date-only, Time-only or DateAndTime.
|
|
47
|
+
*
|
|
48
|
+
* E.g `inTimezone('America/New_York').toISOTime()`
|
|
49
|
+
*
|
|
50
|
+
* https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
|
51
|
+
*
|
|
52
|
+
* @experimental
|
|
53
|
+
*/
|
|
54
|
+
inTimezone(tz: string): WallTime;
|
|
55
|
+
/**
|
|
56
|
+
* UTC offset is the opposite of "timezone offset" - it's the number of minutes to add
|
|
57
|
+
* to the local time to get UTC time.
|
|
58
|
+
*
|
|
59
|
+
* E.g utcOffset for CEST is -120,
|
|
60
|
+
* which means that you need to add -120 minutes to the local time to get UTC time.
|
|
61
|
+
*
|
|
62
|
+
* Instead of -0 it returns 0, for the peace of mind and less weird test/snapshot differences.
|
|
63
|
+
*
|
|
64
|
+
* If timezone (tz) is specified, e.g `America/New_York`,
|
|
65
|
+
* it will return the UTC offset for that timezone.
|
|
66
|
+
*
|
|
67
|
+
* https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
|
68
|
+
*/
|
|
69
|
+
getUTCOffsetMinutes(tz?: string): NumberOfMinutes;
|
|
70
|
+
/**
|
|
71
|
+
* Same as getUTCOffsetMinutes, but rounded to hours.
|
|
72
|
+
*
|
|
73
|
+
* E.g for CEST it is -2.
|
|
74
|
+
*
|
|
75
|
+
* Instead of -0 it returns 0, for the peace of mind and less weird test/snapshot differences.
|
|
76
|
+
*
|
|
77
|
+
* If timezone (tz) is specified, e.g `America/New_York`,
|
|
78
|
+
* it will return the UTC offset for that timezone.
|
|
79
|
+
*/
|
|
80
|
+
getUTCOffsetHours(tz?: string): NumberOfHours;
|
|
81
|
+
/**
|
|
82
|
+
* Returns e.g `-05:00` for New_York winter time.
|
|
83
|
+
*/
|
|
84
|
+
getUTCOffsetString(tz: string): string;
|
|
39
85
|
get(unit: LocalTimeUnit): number;
|
|
40
86
|
set(unit: LocalTimeUnit, v: number, mutate?: boolean): LocalTime;
|
|
41
87
|
year(): number;
|
|
@@ -57,7 +103,7 @@ export declare class LocalTime {
|
|
|
57
103
|
minute(v: number): LocalTime;
|
|
58
104
|
second(): number;
|
|
59
105
|
second(v: number): LocalTime;
|
|
60
|
-
setComponents(c: Partial<
|
|
106
|
+
setComponents(c: Partial<DateTimeObject>, mutate?: boolean): LocalTime;
|
|
61
107
|
plusSeconds(num: number): LocalTime;
|
|
62
108
|
plusMinutes(num: number): LocalTime;
|
|
63
109
|
plusHours(num: number): LocalTime;
|
|
@@ -123,9 +169,9 @@ export declare class LocalTime {
|
|
|
123
169
|
* returns -1 if this < d
|
|
124
170
|
*/
|
|
125
171
|
cmp(d: LocalTimeInput): -1 | 0 | 1;
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
172
|
+
getDateTimeObject(): DateTimeObject;
|
|
173
|
+
getDateObject(): DateObject;
|
|
174
|
+
getTimeObject(): TimeObject;
|
|
129
175
|
fromNow(now?: LocalTimeInput): string;
|
|
130
176
|
getDate(): Date;
|
|
131
177
|
clone(): LocalTime;
|
|
@@ -177,6 +223,19 @@ declare class LocalTimeFactory {
|
|
|
177
223
|
parseToDate(d: LocalTimeInput): Date;
|
|
178
224
|
parseToUnixTimestamp(d: LocalTimeInput): UnixTimestampNumber;
|
|
179
225
|
isValid(d: LocalTimeInput | undefined | null): boolean;
|
|
226
|
+
/**
|
|
227
|
+
* Returns the IANA timezone e.g `Europe/Stockholm`.
|
|
228
|
+
* https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
|
229
|
+
*/
|
|
230
|
+
getTimezone(): string;
|
|
231
|
+
/**
|
|
232
|
+
* Returns true if passed IANA timezone is valid/supported.
|
|
233
|
+
* E.g `Europe/Stockholm` is valid, but `Europe/Stockholm2` is not.
|
|
234
|
+
*
|
|
235
|
+
* This implementation is not optimized for performance. If you need frequent validation -
|
|
236
|
+
* consider caching the Intl.supportedValuesOf values as Set and reuse that.
|
|
237
|
+
*/
|
|
238
|
+
isTimezoneValid(tz: string): boolean;
|
|
180
239
|
now(): LocalTime;
|
|
181
240
|
/**
|
|
182
241
|
* Creates a LocalTime from the input, unless it's falsy - then returns undefined.
|
|
@@ -191,7 +250,7 @@ declare class LocalTimeFactory {
|
|
|
191
250
|
fromComponents(c: {
|
|
192
251
|
year: number;
|
|
193
252
|
month: number;
|
|
194
|
-
} & Partial<
|
|
253
|
+
} & Partial<DateTimeObject>): LocalTime;
|
|
195
254
|
sort(items: LocalTime[], dir?: SortDirection, mutate?: boolean): LocalTime[];
|
|
196
255
|
minOrUndefined(items: LocalTimeInput[]): LocalTime | undefined;
|
|
197
256
|
min(items: LocalTimeInput[]): LocalTime;
|
|
@@ -207,22 +266,4 @@ export declare const localTime: LocalTimeFn;
|
|
|
207
266
|
Like Date.now(), but in seconds.
|
|
208
267
|
*/
|
|
209
268
|
export declare function nowUnix(): UnixTimestampNumber;
|
|
210
|
-
/**
|
|
211
|
-
* UTC offset is the opposite of "timezone offset" - it's the number of minutes to add
|
|
212
|
-
* to the local time to get UTC time.
|
|
213
|
-
*
|
|
214
|
-
* E.g utcOffset for CEST is -120,
|
|
215
|
-
* which means that you need to add -120 minutes to the local time to get UTC time.
|
|
216
|
-
*
|
|
217
|
-
* Instead of -0 it returns 0, for the peace of mind and less weird test/snapshot differences.
|
|
218
|
-
*/
|
|
219
|
-
export declare function getUTCOffsetMinutes(): NumberOfMinutes;
|
|
220
|
-
/**
|
|
221
|
-
* Same as getUTCOffsetMinutes, but rounded to hours.
|
|
222
|
-
*
|
|
223
|
-
* E.g for CEST it is -2.
|
|
224
|
-
*
|
|
225
|
-
* Instead of -0 it returns 0, for the peace of mind and less weird test/snapshot differences.
|
|
226
|
-
*/
|
|
227
|
-
export declare function getUTCOffsetHours(): NumberOfHours;
|
|
228
269
|
export {};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.nowUnix = exports.localTime = exports.LocalTime = exports.ISODayOfWeek = void 0;
|
|
4
4
|
const assert_1 = require("../error/assert");
|
|
5
5
|
const time_util_1 = require("../time/time.util");
|
|
6
6
|
const localDate_1 = require("./localDate");
|
|
7
|
+
const wallTime_1 = require("./wallTime");
|
|
7
8
|
var ISODayOfWeek;
|
|
8
9
|
(function (ISODayOfWeek) {
|
|
9
10
|
ISODayOfWeek[ISODayOfWeek["MONDAY"] = 1] = "MONDAY";
|
|
@@ -38,6 +39,78 @@ class LocalTime {
|
|
|
38
39
|
local() {
|
|
39
40
|
return new LocalTime(new Date(this.$date.getTime()));
|
|
40
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Returns [cloned] fake LocalTime that has yyyy-mm-dd hh:mm:ss in the provided timezone.
|
|
44
|
+
* It is a fake LocalTime in a sense that it's timezone is not real.
|
|
45
|
+
* See this ("common errors"): https://stackoverflow.com/a/15171030/4919972
|
|
46
|
+
* Fake also means that unixTimestamp of that new LocalDate is not the same.
|
|
47
|
+
* For that reason we return WallTime, and not a LocalTime.
|
|
48
|
+
* WallTime can be pretty-printed as Date-only, Time-only or DateAndTime.
|
|
49
|
+
*
|
|
50
|
+
* E.g `inTimezone('America/New_York').toISOTime()`
|
|
51
|
+
*
|
|
52
|
+
* https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
|
53
|
+
*
|
|
54
|
+
* @experimental
|
|
55
|
+
*/
|
|
56
|
+
inTimezone(tz) {
|
|
57
|
+
const d = new Date(this.$date.toLocaleString('en-US', { timeZone: tz }));
|
|
58
|
+
return new wallTime_1.WallTime({
|
|
59
|
+
year: d.getFullYear(),
|
|
60
|
+
month: d.getMonth() + 1,
|
|
61
|
+
day: d.getDate(),
|
|
62
|
+
hour: d.getHours(),
|
|
63
|
+
minute: d.getMinutes(),
|
|
64
|
+
second: d.getSeconds(),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* UTC offset is the opposite of "timezone offset" - it's the number of minutes to add
|
|
69
|
+
* to the local time to get UTC time.
|
|
70
|
+
*
|
|
71
|
+
* E.g utcOffset for CEST is -120,
|
|
72
|
+
* which means that you need to add -120 minutes to the local time to get UTC time.
|
|
73
|
+
*
|
|
74
|
+
* Instead of -0 it returns 0, for the peace of mind and less weird test/snapshot differences.
|
|
75
|
+
*
|
|
76
|
+
* If timezone (tz) is specified, e.g `America/New_York`,
|
|
77
|
+
* it will return the UTC offset for that timezone.
|
|
78
|
+
*
|
|
79
|
+
* https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
|
80
|
+
*/
|
|
81
|
+
getUTCOffsetMinutes(tz) {
|
|
82
|
+
if (tz) {
|
|
83
|
+
// based on: https://stackoverflow.com/a/53652131/4919972
|
|
84
|
+
const nowTime = this.$date.getTime();
|
|
85
|
+
const tzTime = new Date(this.$date.toLocaleString('en-US', { timeZone: tz })).getTime();
|
|
86
|
+
return Math.round((tzTime - nowTime) / 60000) || 0;
|
|
87
|
+
}
|
|
88
|
+
return -this.$date.getTimezoneOffset() || 0;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Same as getUTCOffsetMinutes, but rounded to hours.
|
|
92
|
+
*
|
|
93
|
+
* E.g for CEST it is -2.
|
|
94
|
+
*
|
|
95
|
+
* Instead of -0 it returns 0, for the peace of mind and less weird test/snapshot differences.
|
|
96
|
+
*
|
|
97
|
+
* If timezone (tz) is specified, e.g `America/New_York`,
|
|
98
|
+
* it will return the UTC offset for that timezone.
|
|
99
|
+
*/
|
|
100
|
+
getUTCOffsetHours(tz) {
|
|
101
|
+
return Math.round(this.getUTCOffsetMinutes(tz) / 60);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Returns e.g `-05:00` for New_York winter time.
|
|
105
|
+
*/
|
|
106
|
+
getUTCOffsetString(tz) {
|
|
107
|
+
const minutes = this.getUTCOffsetMinutes(tz);
|
|
108
|
+
const hours = Math.trunc(minutes / 60);
|
|
109
|
+
const sign = hours < 0 ? '-' : '+';
|
|
110
|
+
const h = String(Math.abs(hours)).padStart(2, '0');
|
|
111
|
+
const m = String(minutes % 60).padStart(2, '0');
|
|
112
|
+
return `${sign}${h}:${m}`;
|
|
113
|
+
}
|
|
41
114
|
get(unit) {
|
|
42
115
|
if (unit === 'year') {
|
|
43
116
|
return this.$date.getFullYear();
|
|
@@ -357,20 +430,20 @@ class LocalTime {
|
|
|
357
430
|
return 0;
|
|
358
431
|
return t1 < t2 ? -1 : 1;
|
|
359
432
|
}
|
|
360
|
-
|
|
433
|
+
getDateTimeObject() {
|
|
361
434
|
return {
|
|
362
|
-
...this.
|
|
363
|
-
...this.
|
|
435
|
+
...this.getDateObject(),
|
|
436
|
+
...this.getTimeObject(),
|
|
364
437
|
};
|
|
365
438
|
}
|
|
366
|
-
|
|
439
|
+
getDateObject() {
|
|
367
440
|
return {
|
|
368
441
|
year: this.$date.getFullYear(),
|
|
369
442
|
month: this.$date.getMonth() + 1,
|
|
370
443
|
day: this.$date.getDate(),
|
|
371
444
|
};
|
|
372
445
|
}
|
|
373
|
-
|
|
446
|
+
getTimeObject() {
|
|
374
447
|
return {
|
|
375
448
|
hour: this.$date.getHours(),
|
|
376
449
|
minute: this.$date.getMinutes(),
|
|
@@ -427,7 +500,7 @@ class LocalTime {
|
|
|
427
500
|
* Returns e.g: `1984-06-21`, only the date part of DateTime
|
|
428
501
|
*/
|
|
429
502
|
toISODate() {
|
|
430
|
-
const { year, month, day } = this.
|
|
503
|
+
const { year, month, day } = this.getDateObject();
|
|
431
504
|
return [
|
|
432
505
|
String(year).padStart(4, '0'),
|
|
433
506
|
String(month).padStart(2, '0'),
|
|
@@ -440,7 +513,7 @@ class LocalTime {
|
|
|
440
513
|
* Returns e.g: `17:03:15` (or `17:03` with seconds=false)
|
|
441
514
|
*/
|
|
442
515
|
toISOTime(seconds = true) {
|
|
443
|
-
const { hour, minute, second } = this.
|
|
516
|
+
const { hour, minute, second } = this.getTimeObject();
|
|
444
517
|
return [
|
|
445
518
|
String(hour).padStart(2, '0'),
|
|
446
519
|
String(minute).padStart(2, '0'),
|
|
@@ -455,7 +528,7 @@ class LocalTime {
|
|
|
455
528
|
* Returns e.g: `19840621_1705`
|
|
456
529
|
*/
|
|
457
530
|
toStringCompact(seconds = false) {
|
|
458
|
-
const { year, month, day, hour, minute, second } = this.
|
|
531
|
+
const { year, month, day, hour, minute, second } = this.getDateTimeObject();
|
|
459
532
|
return [
|
|
460
533
|
String(year).padStart(4, '0'),
|
|
461
534
|
String(month).padStart(2, '0'),
|
|
@@ -560,6 +633,23 @@ class LocalTimeFactory {
|
|
|
560
633
|
isValid(d) {
|
|
561
634
|
return this.parseOrNull(d) !== null;
|
|
562
635
|
}
|
|
636
|
+
/**
|
|
637
|
+
* Returns the IANA timezone e.g `Europe/Stockholm`.
|
|
638
|
+
* https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
|
639
|
+
*/
|
|
640
|
+
getTimezone() {
|
|
641
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Returns true if passed IANA timezone is valid/supported.
|
|
645
|
+
* E.g `Europe/Stockholm` is valid, but `Europe/Stockholm2` is not.
|
|
646
|
+
*
|
|
647
|
+
* This implementation is not optimized for performance. If you need frequent validation -
|
|
648
|
+
* consider caching the Intl.supportedValuesOf values as Set and reuse that.
|
|
649
|
+
*/
|
|
650
|
+
isTimezoneValid(tz) {
|
|
651
|
+
return Intl.supportedValuesOf('timeZone').includes(tz);
|
|
652
|
+
}
|
|
563
653
|
now() {
|
|
564
654
|
return new LocalTime(new Date());
|
|
565
655
|
}
|
|
@@ -710,27 +800,3 @@ function nowUnix() {
|
|
|
710
800
|
return Math.floor(Date.now() / 1000);
|
|
711
801
|
}
|
|
712
802
|
exports.nowUnix = nowUnix;
|
|
713
|
-
/**
|
|
714
|
-
* UTC offset is the opposite of "timezone offset" - it's the number of minutes to add
|
|
715
|
-
* to the local time to get UTC time.
|
|
716
|
-
*
|
|
717
|
-
* E.g utcOffset for CEST is -120,
|
|
718
|
-
* which means that you need to add -120 minutes to the local time to get UTC time.
|
|
719
|
-
*
|
|
720
|
-
* Instead of -0 it returns 0, for the peace of mind and less weird test/snapshot differences.
|
|
721
|
-
*/
|
|
722
|
-
function getUTCOffsetMinutes() {
|
|
723
|
-
return -new Date().getTimezoneOffset() || 0;
|
|
724
|
-
}
|
|
725
|
-
exports.getUTCOffsetMinutes = getUTCOffsetMinutes;
|
|
726
|
-
/**
|
|
727
|
-
* Same as getUTCOffsetMinutes, but rounded to hours.
|
|
728
|
-
*
|
|
729
|
-
* E.g for CEST it is -2.
|
|
730
|
-
*
|
|
731
|
-
* Instead of -0 it returns 0, for the peace of mind and less weird test/snapshot differences.
|
|
732
|
-
*/
|
|
733
|
-
function getUTCOffsetHours() {
|
|
734
|
-
return Math.round(getUTCOffsetMinutes() / 60);
|
|
735
|
-
}
|
|
736
|
-
exports.getUTCOffsetHours = getUTCOffsetHours;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { DateTimeObject } from './localTime';
|
|
2
|
+
/**
|
|
3
|
+
* Representation of a "time on the wall clock",
|
|
4
|
+
* which means "local time, regardless of timezone".
|
|
5
|
+
*
|
|
6
|
+
* Experimental simplified container object to hold
|
|
7
|
+
* date and time components as numbers.
|
|
8
|
+
* No math or manipulation is possible here.
|
|
9
|
+
* Can be pretty-printed as Date, Time or DateAndTime.
|
|
10
|
+
*/
|
|
11
|
+
export declare class WallTime implements DateTimeObject {
|
|
12
|
+
year: number;
|
|
13
|
+
month: number;
|
|
14
|
+
day: number;
|
|
15
|
+
hour: number;
|
|
16
|
+
minute: number;
|
|
17
|
+
second: number;
|
|
18
|
+
constructor(obj: DateTimeObject);
|
|
19
|
+
/**
|
|
20
|
+
* Returns e.g: `1984-06-21 17:56:21`
|
|
21
|
+
* or (if seconds=false):
|
|
22
|
+
* `1984-06-21 17:56`
|
|
23
|
+
*/
|
|
24
|
+
toPretty(seconds?: boolean): string;
|
|
25
|
+
/**
|
|
26
|
+
* Returns e.g: `1984-06-21`, only the date part of DateTime
|
|
27
|
+
*/
|
|
28
|
+
toISODate(): string;
|
|
29
|
+
/**
|
|
30
|
+
* Returns e.g: `17:03:15` (or `17:03` with seconds=false)
|
|
31
|
+
*/
|
|
32
|
+
toISOTime(seconds?: boolean): string;
|
|
33
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WallTime = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Representation of a "time on the wall clock",
|
|
6
|
+
* which means "local time, regardless of timezone".
|
|
7
|
+
*
|
|
8
|
+
* Experimental simplified container object to hold
|
|
9
|
+
* date and time components as numbers.
|
|
10
|
+
* No math or manipulation is possible here.
|
|
11
|
+
* Can be pretty-printed as Date, Time or DateAndTime.
|
|
12
|
+
*/
|
|
13
|
+
class WallTime {
|
|
14
|
+
constructor(obj) {
|
|
15
|
+
Object.assign(this, obj);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Returns e.g: `1984-06-21 17:56:21`
|
|
19
|
+
* or (if seconds=false):
|
|
20
|
+
* `1984-06-21 17:56`
|
|
21
|
+
*/
|
|
22
|
+
toPretty(seconds = true) {
|
|
23
|
+
return this.toISODate() + ' ' + this.toISOTime(seconds);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Returns e.g: `1984-06-21`, only the date part of DateTime
|
|
27
|
+
*/
|
|
28
|
+
toISODate() {
|
|
29
|
+
return [
|
|
30
|
+
String(this.year).padStart(4, '0'),
|
|
31
|
+
String(this.month).padStart(2, '0'),
|
|
32
|
+
String(this.day).padStart(2, '0'),
|
|
33
|
+
].join('-');
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Returns e.g: `17:03:15` (or `17:03` with seconds=false)
|
|
37
|
+
*/
|
|
38
|
+
toISOTime(seconds = true) {
|
|
39
|
+
return [
|
|
40
|
+
String(this.hour).padStart(2, '0'),
|
|
41
|
+
String(this.minute).padStart(2, '0'),
|
|
42
|
+
seconds && String(this.second).padStart(2, '0'),
|
|
43
|
+
]
|
|
44
|
+
.filter(Boolean)
|
|
45
|
+
.join(':');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.WallTime = WallTime;
|
package/dist/index.d.ts
CHANGED
|
@@ -26,7 +26,6 @@ export * from './json-schema/jsonSchema.cnst';
|
|
|
26
26
|
export * from './json-schema/jsonSchema.model';
|
|
27
27
|
export * from './json-schema/jsonSchema.util';
|
|
28
28
|
export * from './json-schema/jsonSchemaBuilder';
|
|
29
|
-
export * from './json-schema/jsonSchemaBuilder';
|
|
30
29
|
export * from './math/math.util';
|
|
31
30
|
export * from './math/sma';
|
|
32
31
|
export * from './number/createDeterministicRandom';
|
|
@@ -68,10 +67,7 @@ export * from './math/stack.util';
|
|
|
68
67
|
export * from './string/leven';
|
|
69
68
|
export * from './datetime/localDate';
|
|
70
69
|
export * from './datetime/localTime';
|
|
71
|
-
export * from './datetime/
|
|
72
|
-
export * from './datetime/timeInterval';
|
|
73
|
-
export * from './datetime/localDate';
|
|
74
|
-
export * from './datetime/localTime';
|
|
70
|
+
export * from './datetime/wallTime';
|
|
75
71
|
export * from './datetime/dateInterval';
|
|
76
72
|
export * from './datetime/timeInterval';
|
|
77
73
|
export * from './env';
|
package/dist/index.js
CHANGED
|
@@ -30,7 +30,6 @@ tslib_1.__exportStar(require("./json-schema/jsonSchema.cnst"), exports);
|
|
|
30
30
|
tslib_1.__exportStar(require("./json-schema/jsonSchema.model"), exports);
|
|
31
31
|
tslib_1.__exportStar(require("./json-schema/jsonSchema.util"), exports);
|
|
32
32
|
tslib_1.__exportStar(require("./json-schema/jsonSchemaBuilder"), exports);
|
|
33
|
-
tslib_1.__exportStar(require("./json-schema/jsonSchemaBuilder"), exports);
|
|
34
33
|
tslib_1.__exportStar(require("./math/math.util"), exports);
|
|
35
34
|
tslib_1.__exportStar(require("./math/sma"), exports);
|
|
36
35
|
tslib_1.__exportStar(require("./number/createDeterministicRandom"), exports);
|
|
@@ -72,10 +71,7 @@ tslib_1.__exportStar(require("./math/stack.util"), exports);
|
|
|
72
71
|
tslib_1.__exportStar(require("./string/leven"), exports);
|
|
73
72
|
tslib_1.__exportStar(require("./datetime/localDate"), exports);
|
|
74
73
|
tslib_1.__exportStar(require("./datetime/localTime"), exports);
|
|
75
|
-
tslib_1.__exportStar(require("./datetime/
|
|
76
|
-
tslib_1.__exportStar(require("./datetime/timeInterval"), exports);
|
|
77
|
-
tslib_1.__exportStar(require("./datetime/localDate"), exports);
|
|
78
|
-
tslib_1.__exportStar(require("./datetime/localTime"), exports);
|
|
74
|
+
tslib_1.__exportStar(require("./datetime/wallTime"), exports);
|
|
79
75
|
tslib_1.__exportStar(require("./datetime/dateInterval"), exports);
|
|
80
76
|
tslib_1.__exportStar(require("./datetime/timeInterval"), exports);
|
|
81
77
|
tslib_1.__exportStar(require("./env"), exports);
|
|
@@ -320,6 +320,13 @@ export class LocalDate {
|
|
|
320
320
|
toDateInUTC() {
|
|
321
321
|
return new Date(this.toISODateTimeInUTC());
|
|
322
322
|
}
|
|
323
|
+
toDateObject() {
|
|
324
|
+
return {
|
|
325
|
+
year: this.$year,
|
|
326
|
+
month: this.$month,
|
|
327
|
+
day: this.$day,
|
|
328
|
+
};
|
|
329
|
+
}
|
|
323
330
|
/**
|
|
324
331
|
* Converts LocalDate to LocalTime with 0 hours, 0 minutes, 0 seconds.
|
|
325
332
|
* LocalTime's Date will be in local timezone.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { _assert } from '../error/assert';
|
|
2
2
|
import { _ms } from '../time/time.util';
|
|
3
3
|
import { localDate } from './localDate';
|
|
4
|
+
import { WallTime } from './wallTime';
|
|
4
5
|
export var ISODayOfWeek;
|
|
5
6
|
(function (ISODayOfWeek) {
|
|
6
7
|
ISODayOfWeek[ISODayOfWeek["MONDAY"] = 1] = "MONDAY";
|
|
@@ -35,6 +36,78 @@ export class LocalTime {
|
|
|
35
36
|
local() {
|
|
36
37
|
return new LocalTime(new Date(this.$date.getTime()));
|
|
37
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Returns [cloned] fake LocalTime that has yyyy-mm-dd hh:mm:ss in the provided timezone.
|
|
41
|
+
* It is a fake LocalTime in a sense that it's timezone is not real.
|
|
42
|
+
* See this ("common errors"): https://stackoverflow.com/a/15171030/4919972
|
|
43
|
+
* Fake also means that unixTimestamp of that new LocalDate is not the same.
|
|
44
|
+
* For that reason we return WallTime, and not a LocalTime.
|
|
45
|
+
* WallTime can be pretty-printed as Date-only, Time-only or DateAndTime.
|
|
46
|
+
*
|
|
47
|
+
* E.g `inTimezone('America/New_York').toISOTime()`
|
|
48
|
+
*
|
|
49
|
+
* https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
|
50
|
+
*
|
|
51
|
+
* @experimental
|
|
52
|
+
*/
|
|
53
|
+
inTimezone(tz) {
|
|
54
|
+
const d = new Date(this.$date.toLocaleString('en-US', { timeZone: tz }));
|
|
55
|
+
return new WallTime({
|
|
56
|
+
year: d.getFullYear(),
|
|
57
|
+
month: d.getMonth() + 1,
|
|
58
|
+
day: d.getDate(),
|
|
59
|
+
hour: d.getHours(),
|
|
60
|
+
minute: d.getMinutes(),
|
|
61
|
+
second: d.getSeconds(),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* UTC offset is the opposite of "timezone offset" - it's the number of minutes to add
|
|
66
|
+
* to the local time to get UTC time.
|
|
67
|
+
*
|
|
68
|
+
* E.g utcOffset for CEST is -120,
|
|
69
|
+
* which means that you need to add -120 minutes to the local time to get UTC time.
|
|
70
|
+
*
|
|
71
|
+
* Instead of -0 it returns 0, for the peace of mind and less weird test/snapshot differences.
|
|
72
|
+
*
|
|
73
|
+
* If timezone (tz) is specified, e.g `America/New_York`,
|
|
74
|
+
* it will return the UTC offset for that timezone.
|
|
75
|
+
*
|
|
76
|
+
* https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
|
77
|
+
*/
|
|
78
|
+
getUTCOffsetMinutes(tz) {
|
|
79
|
+
if (tz) {
|
|
80
|
+
// based on: https://stackoverflow.com/a/53652131/4919972
|
|
81
|
+
const nowTime = this.$date.getTime();
|
|
82
|
+
const tzTime = new Date(this.$date.toLocaleString('en-US', { timeZone: tz })).getTime();
|
|
83
|
+
return Math.round((tzTime - nowTime) / 60000) || 0;
|
|
84
|
+
}
|
|
85
|
+
return -this.$date.getTimezoneOffset() || 0;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Same as getUTCOffsetMinutes, but rounded to hours.
|
|
89
|
+
*
|
|
90
|
+
* E.g for CEST it is -2.
|
|
91
|
+
*
|
|
92
|
+
* Instead of -0 it returns 0, for the peace of mind and less weird test/snapshot differences.
|
|
93
|
+
*
|
|
94
|
+
* If timezone (tz) is specified, e.g `America/New_York`,
|
|
95
|
+
* it will return the UTC offset for that timezone.
|
|
96
|
+
*/
|
|
97
|
+
getUTCOffsetHours(tz) {
|
|
98
|
+
return Math.round(this.getUTCOffsetMinutes(tz) / 60);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Returns e.g `-05:00` for New_York winter time.
|
|
102
|
+
*/
|
|
103
|
+
getUTCOffsetString(tz) {
|
|
104
|
+
const minutes = this.getUTCOffsetMinutes(tz);
|
|
105
|
+
const hours = Math.trunc(minutes / 60);
|
|
106
|
+
const sign = hours < 0 ? '-' : '+';
|
|
107
|
+
const h = String(Math.abs(hours)).padStart(2, '0');
|
|
108
|
+
const m = String(minutes % 60).padStart(2, '0');
|
|
109
|
+
return `${sign}${h}:${m}`;
|
|
110
|
+
}
|
|
38
111
|
get(unit) {
|
|
39
112
|
if (unit === 'year') {
|
|
40
113
|
return this.$date.getFullYear();
|
|
@@ -354,20 +427,20 @@ export class LocalTime {
|
|
|
354
427
|
return 0;
|
|
355
428
|
return t1 < t2 ? -1 : 1;
|
|
356
429
|
}
|
|
357
|
-
|
|
430
|
+
getDateTimeObject() {
|
|
358
431
|
return {
|
|
359
|
-
...this.
|
|
360
|
-
...this.
|
|
432
|
+
...this.getDateObject(),
|
|
433
|
+
...this.getTimeObject(),
|
|
361
434
|
};
|
|
362
435
|
}
|
|
363
|
-
|
|
436
|
+
getDateObject() {
|
|
364
437
|
return {
|
|
365
438
|
year: this.$date.getFullYear(),
|
|
366
439
|
month: this.$date.getMonth() + 1,
|
|
367
440
|
day: this.$date.getDate(),
|
|
368
441
|
};
|
|
369
442
|
}
|
|
370
|
-
|
|
443
|
+
getTimeObject() {
|
|
371
444
|
return {
|
|
372
445
|
hour: this.$date.getHours(),
|
|
373
446
|
minute: this.$date.getMinutes(),
|
|
@@ -424,7 +497,7 @@ export class LocalTime {
|
|
|
424
497
|
* Returns e.g: `1984-06-21`, only the date part of DateTime
|
|
425
498
|
*/
|
|
426
499
|
toISODate() {
|
|
427
|
-
const { year, month, day } = this.
|
|
500
|
+
const { year, month, day } = this.getDateObject();
|
|
428
501
|
return [
|
|
429
502
|
String(year).padStart(4, '0'),
|
|
430
503
|
String(month).padStart(2, '0'),
|
|
@@ -437,7 +510,7 @@ export class LocalTime {
|
|
|
437
510
|
* Returns e.g: `17:03:15` (or `17:03` with seconds=false)
|
|
438
511
|
*/
|
|
439
512
|
toISOTime(seconds = true) {
|
|
440
|
-
const { hour, minute, second } = this.
|
|
513
|
+
const { hour, minute, second } = this.getTimeObject();
|
|
441
514
|
return [
|
|
442
515
|
String(hour).padStart(2, '0'),
|
|
443
516
|
String(minute).padStart(2, '0'),
|
|
@@ -452,7 +525,7 @@ export class LocalTime {
|
|
|
452
525
|
* Returns e.g: `19840621_1705`
|
|
453
526
|
*/
|
|
454
527
|
toStringCompact(seconds = false) {
|
|
455
|
-
const { year, month, day, hour, minute, second } = this.
|
|
528
|
+
const { year, month, day, hour, minute, second } = this.getDateTimeObject();
|
|
456
529
|
return [
|
|
457
530
|
String(year).padStart(4, '0'),
|
|
458
531
|
String(month).padStart(2, '0'),
|
|
@@ -556,6 +629,23 @@ class LocalTimeFactory {
|
|
|
556
629
|
isValid(d) {
|
|
557
630
|
return this.parseOrNull(d) !== null;
|
|
558
631
|
}
|
|
632
|
+
/**
|
|
633
|
+
* Returns the IANA timezone e.g `Europe/Stockholm`.
|
|
634
|
+
* https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
|
635
|
+
*/
|
|
636
|
+
getTimezone() {
|
|
637
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* Returns true if passed IANA timezone is valid/supported.
|
|
641
|
+
* E.g `Europe/Stockholm` is valid, but `Europe/Stockholm2` is not.
|
|
642
|
+
*
|
|
643
|
+
* This implementation is not optimized for performance. If you need frequent validation -
|
|
644
|
+
* consider caching the Intl.supportedValuesOf values as Set and reuse that.
|
|
645
|
+
*/
|
|
646
|
+
isTimezoneValid(tz) {
|
|
647
|
+
return Intl.supportedValuesOf('timeZone').includes(tz);
|
|
648
|
+
}
|
|
559
649
|
now() {
|
|
560
650
|
return new LocalTime(new Date());
|
|
561
651
|
}
|
|
@@ -705,25 +795,3 @@ Object.setPrototypeOf(localTime, localTimeFactory);
|
|
|
705
795
|
export function nowUnix() {
|
|
706
796
|
return Math.floor(Date.now() / 1000);
|
|
707
797
|
}
|
|
708
|
-
/**
|
|
709
|
-
* UTC offset is the opposite of "timezone offset" - it's the number of minutes to add
|
|
710
|
-
* to the local time to get UTC time.
|
|
711
|
-
*
|
|
712
|
-
* E.g utcOffset for CEST is -120,
|
|
713
|
-
* which means that you need to add -120 minutes to the local time to get UTC time.
|
|
714
|
-
*
|
|
715
|
-
* Instead of -0 it returns 0, for the peace of mind and less weird test/snapshot differences.
|
|
716
|
-
*/
|
|
717
|
-
export function getUTCOffsetMinutes() {
|
|
718
|
-
return -new Date().getTimezoneOffset() || 0;
|
|
719
|
-
}
|
|
720
|
-
/**
|
|
721
|
-
* Same as getUTCOffsetMinutes, but rounded to hours.
|
|
722
|
-
*
|
|
723
|
-
* E.g for CEST it is -2.
|
|
724
|
-
*
|
|
725
|
-
* Instead of -0 it returns 0, for the peace of mind and less weird test/snapshot differences.
|
|
726
|
-
*/
|
|
727
|
-
export function getUTCOffsetHours() {
|
|
728
|
-
return Math.round(getUTCOffsetMinutes() / 60);
|
|
729
|
-
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Representation of a "time on the wall clock",
|
|
3
|
+
* which means "local time, regardless of timezone".
|
|
4
|
+
*
|
|
5
|
+
* Experimental simplified container object to hold
|
|
6
|
+
* date and time components as numbers.
|
|
7
|
+
* No math or manipulation is possible here.
|
|
8
|
+
* Can be pretty-printed as Date, Time or DateAndTime.
|
|
9
|
+
*/
|
|
10
|
+
export class WallTime {
|
|
11
|
+
constructor(obj) {
|
|
12
|
+
Object.assign(this, obj);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Returns e.g: `1984-06-21 17:56:21`
|
|
16
|
+
* or (if seconds=false):
|
|
17
|
+
* `1984-06-21 17:56`
|
|
18
|
+
*/
|
|
19
|
+
toPretty(seconds = true) {
|
|
20
|
+
return this.toISODate() + ' ' + this.toISOTime(seconds);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Returns e.g: `1984-06-21`, only the date part of DateTime
|
|
24
|
+
*/
|
|
25
|
+
toISODate() {
|
|
26
|
+
return [
|
|
27
|
+
String(this.year).padStart(4, '0'),
|
|
28
|
+
String(this.month).padStart(2, '0'),
|
|
29
|
+
String(this.day).padStart(2, '0'),
|
|
30
|
+
].join('-');
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Returns e.g: `17:03:15` (or `17:03` with seconds=false)
|
|
34
|
+
*/
|
|
35
|
+
toISOTime(seconds = true) {
|
|
36
|
+
return [
|
|
37
|
+
String(this.hour).padStart(2, '0'),
|
|
38
|
+
String(this.minute).padStart(2, '0'),
|
|
39
|
+
seconds && String(this.second).padStart(2, '0'),
|
|
40
|
+
]
|
|
41
|
+
.filter(Boolean)
|
|
42
|
+
.join(':');
|
|
43
|
+
}
|
|
44
|
+
}
|
package/dist-esm/index.js
CHANGED
|
@@ -26,7 +26,6 @@ export * from './json-schema/jsonSchema.cnst';
|
|
|
26
26
|
export * from './json-schema/jsonSchema.model';
|
|
27
27
|
export * from './json-schema/jsonSchema.util';
|
|
28
28
|
export * from './json-schema/jsonSchemaBuilder';
|
|
29
|
-
export * from './json-schema/jsonSchemaBuilder';
|
|
30
29
|
export * from './math/math.util';
|
|
31
30
|
export * from './math/sma';
|
|
32
31
|
export * from './number/createDeterministicRandom';
|
|
@@ -68,10 +67,7 @@ export * from './math/stack.util';
|
|
|
68
67
|
export * from './string/leven';
|
|
69
68
|
export * from './datetime/localDate';
|
|
70
69
|
export * from './datetime/localTime';
|
|
71
|
-
export * from './datetime/
|
|
72
|
-
export * from './datetime/timeInterval';
|
|
73
|
-
export * from './datetime/localDate';
|
|
74
|
-
export * from './datetime/localTime';
|
|
70
|
+
export * from './datetime/wallTime';
|
|
75
71
|
export * from './datetime/dateInterval';
|
|
76
72
|
export * from './datetime/timeInterval';
|
|
77
73
|
export * from './env';
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
UnixTimestampMillisNumber,
|
|
10
10
|
UnixTimestampNumber,
|
|
11
11
|
} from '../types'
|
|
12
|
-
import { ISODayOfWeek, localTime, LocalTime } from './localTime'
|
|
12
|
+
import { DateObject, ISODayOfWeek, localTime, LocalTime } from './localTime'
|
|
13
13
|
|
|
14
14
|
export type LocalDateUnit = LocalDateUnitStrict | 'week'
|
|
15
15
|
export type LocalDateUnitStrict = 'year' | 'month' | 'day'
|
|
@@ -381,6 +381,14 @@ export class LocalDate {
|
|
|
381
381
|
return new Date(this.toISODateTimeInUTC())
|
|
382
382
|
}
|
|
383
383
|
|
|
384
|
+
toDateObject(): DateObject {
|
|
385
|
+
return {
|
|
386
|
+
year: this.$year,
|
|
387
|
+
month: this.$month,
|
|
388
|
+
day: this.$day,
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
384
392
|
/**
|
|
385
393
|
* Converts LocalDate to LocalTime with 0 hours, 0 minutes, 0 seconds.
|
|
386
394
|
* LocalTime's Date will be in local timezone.
|
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
UnixTimestampNumber,
|
|
13
13
|
} from '../types'
|
|
14
14
|
import { localDate, LocalDate } from './localDate'
|
|
15
|
+
import { WallTime } from './wallTime'
|
|
15
16
|
|
|
16
17
|
export type LocalTimeUnit = 'year' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second'
|
|
17
18
|
|
|
@@ -28,15 +29,15 @@ export enum ISODayOfWeek {
|
|
|
28
29
|
export type LocalTimeInput = LocalTime | Date | IsoDateTimeString | UnixTimestampNumber
|
|
29
30
|
export type LocalTimeFormatter = (ld: LocalTime) => string
|
|
30
31
|
|
|
31
|
-
export type
|
|
32
|
+
export type DateTimeObject = DateObject & TimeObject
|
|
32
33
|
|
|
33
|
-
interface
|
|
34
|
+
export interface DateObject {
|
|
34
35
|
year: number
|
|
35
36
|
month: number
|
|
36
37
|
day: number
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
interface
|
|
40
|
+
export interface TimeObject {
|
|
40
41
|
hour: number
|
|
41
42
|
minute: number
|
|
42
43
|
second: number
|
|
@@ -68,6 +69,83 @@ export class LocalTime {
|
|
|
68
69
|
return new LocalTime(new Date(this.$date.getTime()))
|
|
69
70
|
}
|
|
70
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Returns [cloned] fake LocalTime that has yyyy-mm-dd hh:mm:ss in the provided timezone.
|
|
74
|
+
* It is a fake LocalTime in a sense that it's timezone is not real.
|
|
75
|
+
* See this ("common errors"): https://stackoverflow.com/a/15171030/4919972
|
|
76
|
+
* Fake also means that unixTimestamp of that new LocalDate is not the same.
|
|
77
|
+
* For that reason we return WallTime, and not a LocalTime.
|
|
78
|
+
* WallTime can be pretty-printed as Date-only, Time-only or DateAndTime.
|
|
79
|
+
*
|
|
80
|
+
* E.g `inTimezone('America/New_York').toISOTime()`
|
|
81
|
+
*
|
|
82
|
+
* https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
|
83
|
+
*
|
|
84
|
+
* @experimental
|
|
85
|
+
*/
|
|
86
|
+
inTimezone(tz: string): WallTime {
|
|
87
|
+
const d = new Date(this.$date.toLocaleString('en-US', { timeZone: tz }))
|
|
88
|
+
return new WallTime({
|
|
89
|
+
year: d.getFullYear(),
|
|
90
|
+
month: d.getMonth() + 1,
|
|
91
|
+
day: d.getDate(),
|
|
92
|
+
hour: d.getHours(),
|
|
93
|
+
minute: d.getMinutes(),
|
|
94
|
+
second: d.getSeconds(),
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* UTC offset is the opposite of "timezone offset" - it's the number of minutes to add
|
|
100
|
+
* to the local time to get UTC time.
|
|
101
|
+
*
|
|
102
|
+
* E.g utcOffset for CEST is -120,
|
|
103
|
+
* which means that you need to add -120 minutes to the local time to get UTC time.
|
|
104
|
+
*
|
|
105
|
+
* Instead of -0 it returns 0, for the peace of mind and less weird test/snapshot differences.
|
|
106
|
+
*
|
|
107
|
+
* If timezone (tz) is specified, e.g `America/New_York`,
|
|
108
|
+
* it will return the UTC offset for that timezone.
|
|
109
|
+
*
|
|
110
|
+
* https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
|
111
|
+
*/
|
|
112
|
+
getUTCOffsetMinutes(tz?: string): NumberOfMinutes {
|
|
113
|
+
if (tz) {
|
|
114
|
+
// based on: https://stackoverflow.com/a/53652131/4919972
|
|
115
|
+
const nowTime = this.$date.getTime()
|
|
116
|
+
const tzTime = new Date(this.$date.toLocaleString('en-US', { timeZone: tz })).getTime()
|
|
117
|
+
return Math.round((tzTime - nowTime) / 60000) || 0
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return -this.$date.getTimezoneOffset() || 0
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Same as getUTCOffsetMinutes, but rounded to hours.
|
|
125
|
+
*
|
|
126
|
+
* E.g for CEST it is -2.
|
|
127
|
+
*
|
|
128
|
+
* Instead of -0 it returns 0, for the peace of mind and less weird test/snapshot differences.
|
|
129
|
+
*
|
|
130
|
+
* If timezone (tz) is specified, e.g `America/New_York`,
|
|
131
|
+
* it will return the UTC offset for that timezone.
|
|
132
|
+
*/
|
|
133
|
+
getUTCOffsetHours(tz?: string): NumberOfHours {
|
|
134
|
+
return Math.round(this.getUTCOffsetMinutes(tz) / 60)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Returns e.g `-05:00` for New_York winter time.
|
|
139
|
+
*/
|
|
140
|
+
getUTCOffsetString(tz: string): string {
|
|
141
|
+
const minutes = this.getUTCOffsetMinutes(tz)
|
|
142
|
+
const hours = Math.trunc(minutes / 60)
|
|
143
|
+
const sign = hours < 0 ? '-' : '+'
|
|
144
|
+
const h = String(Math.abs(hours)).padStart(2, '0')
|
|
145
|
+
const m = String(minutes % 60).padStart(2, '0')
|
|
146
|
+
return `${sign}${h}:${m}`
|
|
147
|
+
}
|
|
148
|
+
|
|
71
149
|
get(unit: LocalTimeUnit): number {
|
|
72
150
|
if (unit === 'year') {
|
|
73
151
|
return this.$date.getFullYear()
|
|
@@ -166,7 +244,7 @@ export class LocalTime {
|
|
|
166
244
|
return v === undefined ? this.get('second') : this.set('second', v)
|
|
167
245
|
}
|
|
168
246
|
|
|
169
|
-
setComponents(c: Partial<
|
|
247
|
+
setComponents(c: Partial<DateTimeObject>, mutate = false): LocalTime {
|
|
170
248
|
const d = mutate ? this.$date : new Date(this.$date)
|
|
171
249
|
|
|
172
250
|
// Year, month and day set all-at-once, to avoid 30/31 (and 28/29) mishap
|
|
@@ -434,14 +512,14 @@ export class LocalTime {
|
|
|
434
512
|
return t1 < t2 ? -1 : 1
|
|
435
513
|
}
|
|
436
514
|
|
|
437
|
-
|
|
515
|
+
getDateTimeObject(): DateTimeObject {
|
|
438
516
|
return {
|
|
439
|
-
...this.
|
|
440
|
-
...this.
|
|
517
|
+
...this.getDateObject(),
|
|
518
|
+
...this.getTimeObject(),
|
|
441
519
|
}
|
|
442
520
|
}
|
|
443
521
|
|
|
444
|
-
|
|
522
|
+
getDateObject(): DateObject {
|
|
445
523
|
return {
|
|
446
524
|
year: this.$date.getFullYear(),
|
|
447
525
|
month: this.$date.getMonth() + 1,
|
|
@@ -449,7 +527,7 @@ export class LocalTime {
|
|
|
449
527
|
}
|
|
450
528
|
}
|
|
451
529
|
|
|
452
|
-
|
|
530
|
+
getTimeObject(): TimeObject {
|
|
453
531
|
return {
|
|
454
532
|
hour: this.$date.getHours(),
|
|
455
533
|
minute: this.$date.getMinutes(),
|
|
@@ -518,7 +596,7 @@ export class LocalTime {
|
|
|
518
596
|
* Returns e.g: `1984-06-21`, only the date part of DateTime
|
|
519
597
|
*/
|
|
520
598
|
toISODate(): IsoDateString {
|
|
521
|
-
const { year, month, day } = this.
|
|
599
|
+
const { year, month, day } = this.getDateObject()
|
|
522
600
|
|
|
523
601
|
return [
|
|
524
602
|
String(year).padStart(4, '0'),
|
|
@@ -534,7 +612,7 @@ export class LocalTime {
|
|
|
534
612
|
* Returns e.g: `17:03:15` (or `17:03` with seconds=false)
|
|
535
613
|
*/
|
|
536
614
|
toISOTime(seconds = true): string {
|
|
537
|
-
const { hour, minute, second } = this.
|
|
615
|
+
const { hour, minute, second } = this.getTimeObject()
|
|
538
616
|
|
|
539
617
|
return [
|
|
540
618
|
String(hour).padStart(2, '0'),
|
|
@@ -552,7 +630,7 @@ export class LocalTime {
|
|
|
552
630
|
* Returns e.g: `19840621_1705`
|
|
553
631
|
*/
|
|
554
632
|
toStringCompact(seconds = false): string {
|
|
555
|
-
const { year, month, day, hour, minute, second } = this.
|
|
633
|
+
const { year, month, day, hour, minute, second } = this.getDateTimeObject()
|
|
556
634
|
|
|
557
635
|
return [
|
|
558
636
|
String(year).padStart(4, '0'),
|
|
@@ -672,6 +750,25 @@ class LocalTimeFactory {
|
|
|
672
750
|
return this.parseOrNull(d) !== null
|
|
673
751
|
}
|
|
674
752
|
|
|
753
|
+
/**
|
|
754
|
+
* Returns the IANA timezone e.g `Europe/Stockholm`.
|
|
755
|
+
* https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
|
756
|
+
*/
|
|
757
|
+
getTimezone(): string {
|
|
758
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/**
|
|
762
|
+
* Returns true if passed IANA timezone is valid/supported.
|
|
763
|
+
* E.g `Europe/Stockholm` is valid, but `Europe/Stockholm2` is not.
|
|
764
|
+
*
|
|
765
|
+
* This implementation is not optimized for performance. If you need frequent validation -
|
|
766
|
+
* consider caching the Intl.supportedValuesOf values as Set and reuse that.
|
|
767
|
+
*/
|
|
768
|
+
isTimezoneValid(tz: string): boolean {
|
|
769
|
+
return Intl.supportedValuesOf('timeZone').includes(tz)
|
|
770
|
+
}
|
|
771
|
+
|
|
675
772
|
now(): LocalTime {
|
|
676
773
|
return new LocalTime(new Date())
|
|
677
774
|
}
|
|
@@ -692,7 +789,7 @@ class LocalTimeFactory {
|
|
|
692
789
|
return d ? this.of(d) : this.now()
|
|
693
790
|
}
|
|
694
791
|
|
|
695
|
-
fromComponents(c: { year: number; month: number } & Partial<
|
|
792
|
+
fromComponents(c: { year: number; month: number } & Partial<DateTimeObject>): LocalTime {
|
|
696
793
|
return new LocalTime(
|
|
697
794
|
new Date(c.year, c.month - 1, c.day || 1, c.hour || 0, c.minute || 0, c.second || 0),
|
|
698
795
|
)
|
|
@@ -857,27 +954,3 @@ Object.setPrototypeOf(localTime, localTimeFactory)
|
|
|
857
954
|
export function nowUnix(): UnixTimestampNumber {
|
|
858
955
|
return Math.floor(Date.now() / 1000)
|
|
859
956
|
}
|
|
860
|
-
|
|
861
|
-
/**
|
|
862
|
-
* UTC offset is the opposite of "timezone offset" - it's the number of minutes to add
|
|
863
|
-
* to the local time to get UTC time.
|
|
864
|
-
*
|
|
865
|
-
* E.g utcOffset for CEST is -120,
|
|
866
|
-
* which means that you need to add -120 minutes to the local time to get UTC time.
|
|
867
|
-
*
|
|
868
|
-
* Instead of -0 it returns 0, for the peace of mind and less weird test/snapshot differences.
|
|
869
|
-
*/
|
|
870
|
-
export function getUTCOffsetMinutes(): NumberOfMinutes {
|
|
871
|
-
return -new Date().getTimezoneOffset() || 0
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
/**
|
|
875
|
-
* Same as getUTCOffsetMinutes, but rounded to hours.
|
|
876
|
-
*
|
|
877
|
-
* E.g for CEST it is -2.
|
|
878
|
-
*
|
|
879
|
-
* Instead of -0 it returns 0, for the peace of mind and less weird test/snapshot differences.
|
|
880
|
-
*/
|
|
881
|
-
export function getUTCOffsetHours(): NumberOfHours {
|
|
882
|
-
return Math.round(getUTCOffsetMinutes() / 60)
|
|
883
|
-
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { DateTimeObject } from './localTime'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Representation of a "time on the wall clock",
|
|
5
|
+
* which means "local time, regardless of timezone".
|
|
6
|
+
*
|
|
7
|
+
* Experimental simplified container object to hold
|
|
8
|
+
* date and time components as numbers.
|
|
9
|
+
* No math or manipulation is possible here.
|
|
10
|
+
* Can be pretty-printed as Date, Time or DateAndTime.
|
|
11
|
+
*/
|
|
12
|
+
export class WallTime implements DateTimeObject {
|
|
13
|
+
year!: number
|
|
14
|
+
month!: number
|
|
15
|
+
day!: number
|
|
16
|
+
hour!: number
|
|
17
|
+
minute!: number
|
|
18
|
+
second!: number
|
|
19
|
+
|
|
20
|
+
constructor(obj: DateTimeObject) {
|
|
21
|
+
Object.assign(this, obj)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Returns e.g: `1984-06-21 17:56:21`
|
|
26
|
+
* or (if seconds=false):
|
|
27
|
+
* `1984-06-21 17:56`
|
|
28
|
+
*/
|
|
29
|
+
toPretty(seconds = true): string {
|
|
30
|
+
return this.toISODate() + ' ' + this.toISOTime(seconds)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Returns e.g: `1984-06-21`, only the date part of DateTime
|
|
35
|
+
*/
|
|
36
|
+
toISODate(): string {
|
|
37
|
+
return [
|
|
38
|
+
String(this.year).padStart(4, '0'),
|
|
39
|
+
String(this.month).padStart(2, '0'),
|
|
40
|
+
String(this.day).padStart(2, '0'),
|
|
41
|
+
].join('-')
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Returns e.g: `17:03:15` (or `17:03` with seconds=false)
|
|
46
|
+
*/
|
|
47
|
+
toISOTime(seconds = true): string {
|
|
48
|
+
return [
|
|
49
|
+
String(this.hour).padStart(2, '0'),
|
|
50
|
+
String(this.minute).padStart(2, '0'),
|
|
51
|
+
seconds && String(this.second).padStart(2, '0'),
|
|
52
|
+
]
|
|
53
|
+
.filter(Boolean)
|
|
54
|
+
.join(':')
|
|
55
|
+
}
|
|
56
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -26,7 +26,6 @@ export * from './json-schema/jsonSchema.cnst'
|
|
|
26
26
|
export * from './json-schema/jsonSchema.model'
|
|
27
27
|
export * from './json-schema/jsonSchema.util'
|
|
28
28
|
export * from './json-schema/jsonSchemaBuilder'
|
|
29
|
-
export * from './json-schema/jsonSchemaBuilder'
|
|
30
29
|
export * from './math/math.util'
|
|
31
30
|
export * from './math/sma'
|
|
32
31
|
export * from './number/createDeterministicRandom'
|
|
@@ -68,10 +67,7 @@ export * from './math/stack.util'
|
|
|
68
67
|
export * from './string/leven'
|
|
69
68
|
export * from './datetime/localDate'
|
|
70
69
|
export * from './datetime/localTime'
|
|
71
|
-
export * from './datetime/
|
|
72
|
-
export * from './datetime/timeInterval'
|
|
73
|
-
export * from './datetime/localDate'
|
|
74
|
-
export * from './datetime/localTime'
|
|
70
|
+
export * from './datetime/wallTime'
|
|
75
71
|
export * from './datetime/dateInterval'
|
|
76
72
|
export * from './datetime/timeInterval'
|
|
77
73
|
export * from './env'
|