nhb-toolbox 4.26.21 → 4.26.30
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/CHANGELOG.md +15 -1
- package/dist/cjs/date/Chronos.js +1 -1
- package/dist/cjs/date/plugins/timeZonePlugin.js +56 -22
- package/dist/cjs/date/timezone.js +3 -3
- package/dist/dts/date/Chronos.d.ts +11 -11
- package/dist/dts/date/plugins/businessPlugin.d.ts +2 -2
- package/dist/dts/date/plugins/durationPlugin.d.ts +6 -0
- package/dist/dts/date/plugins/timeZonePlugin.d.ts +15 -6
- package/dist/dts/date/timezone.d.ts +3 -3
- package/dist/dts/date/types.d.ts +1 -0
- package/dist/esm/date/Chronos.js +1 -1
- package/dist/esm/date/plugins/timeZonePlugin.js +56 -22
- package/dist/esm/date/timezone.js +3 -3
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -6,11 +6,25 @@ All notable changes to the package will be documented here.
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
## [4.26.30] - 2025-11-11
|
|
10
|
+
|
|
11
|
+
### 🕧 Updates in Chronos
|
|
12
|
+
|
|
13
|
+
- **Fixed** issues in `getTimeZoneName()` and `getTimeZoneNameShort()` where expected outputs were *missing or incorrect*.
|
|
14
|
+
- **Updated** *timezone constants*vby removing *redundant hints* and *improving internal consistency*.
|
|
15
|
+
- **Introduced** a new *method alias* `getTimeZoneNameAbbr()` for `getTimeZoneNameShort()`.
|
|
16
|
+
- **Fixed** an issue where the `clone()` method *did not correctly duplicate the instance state*.
|
|
17
|
+
|
|
9
18
|
## [4.26.21] - 2025-11-10
|
|
10
19
|
|
|
11
|
-
|
|
20
|
+
### 🕧 Updates in Chronos
|
|
21
|
+
|
|
22
|
+
- **Fixed** issues with `Chronos` timezone methods: `getTimeZoneName()` and `getTimeZoneNameShort()` *not providing name/short name* for *optional UTC*.
|
|
12
23
|
- **Fixed** issues with `Chronos` `diff()` method: now *calculates exact differences for month and year* too.
|
|
13
24
|
- **Changed** the signature of `Chronos` `set()` method to `set<Unit extends TimeUnit>(unit: Unit, value: TimeUnitValue<Unit>): Chronos`. **Created** new type helper `TimeUnitValue<Unit>`.
|
|
25
|
+
|
|
26
|
+
### 🛠️ Other Updates
|
|
27
|
+
|
|
14
28
|
- **Renamed** `isValidUTCOffSet` *guard* as `isValidUTCOffset` and also kept `isValidUTCOffSet` as alias.
|
|
15
29
|
|
|
16
30
|
## [4.26.20] - 2025-11-10
|
package/dist/cjs/date/Chronos.js
CHANGED
|
@@ -284,7 +284,7 @@ class Chronos {
|
|
|
284
284
|
return this.getTimeStamp();
|
|
285
285
|
}
|
|
286
286
|
clone() {
|
|
287
|
-
return new _a(this.#date).#withOrigin(this.#ORIGIN);
|
|
287
|
+
return new _a(this.#date).#withOrigin(this.#ORIGIN, this.#offset, this.timeZoneName, this.timeZoneId, this.$tzTracker);
|
|
288
288
|
}
|
|
289
289
|
toDate() {
|
|
290
290
|
switch (this.#ORIGIN) {
|
|
@@ -7,6 +7,13 @@ const timezone_1 = require("../timezone");
|
|
|
7
7
|
const utils_1 = require("../utils");
|
|
8
8
|
const timeZonePlugin = (ChronosClass) => {
|
|
9
9
|
const { internalDate: $Date, withOrigin } = ChronosClass[constants_1.INTERNALS];
|
|
10
|
+
const _isGMT = (factor) => {
|
|
11
|
+
return factor === 'UTC+00:00' || factor === 'UTC-00:00';
|
|
12
|
+
};
|
|
13
|
+
const TZ_NAME_ABBR_MAP = new Map(Object.entries(timezone_1.TIME_ZONES).map(([tzAbbr, { offset, tzName }]) => [
|
|
14
|
+
offset,
|
|
15
|
+
{ tzAbbr, tzName },
|
|
16
|
+
]));
|
|
10
17
|
const _isLabelKey = (offset) => {
|
|
11
18
|
return offset in timezone_1.TIME_ZONE_LABELS;
|
|
12
19
|
};
|
|
@@ -17,8 +24,14 @@ const timeZonePlugin = (ChronosClass) => {
|
|
|
17
24
|
return undefined;
|
|
18
25
|
};
|
|
19
26
|
const _getTimeZoneName = (zone) => {
|
|
27
|
+
if (_isGMT(zone))
|
|
28
|
+
return 'Greenwich Mean Time';
|
|
20
29
|
if ((0, guards_1.isValidUTCOffset)(zone)) {
|
|
21
|
-
|
|
30
|
+
const tzName = _resolveTzName(zone);
|
|
31
|
+
if (!tzName && TZ_NAME_ABBR_MAP.has(zone)) {
|
|
32
|
+
return TZ_NAME_ABBR_MAP.get(zone)?.tzName;
|
|
33
|
+
}
|
|
34
|
+
return tzName;
|
|
22
35
|
}
|
|
23
36
|
else if ((0, guards_1.isValidTimeZoneId)(zone)) {
|
|
24
37
|
const record = timezone_1.TIME_ZONE_IDS[zone];
|
|
@@ -27,17 +40,17 @@ const timeZonePlugin = (ChronosClass) => {
|
|
|
27
40
|
else {
|
|
28
41
|
return zone in timezone_1.TIME_ZONES ?
|
|
29
42
|
timezone_1.TIME_ZONES[zone].tzName
|
|
30
|
-
: _resolveTzName(timezone_1.TIME_ZONES[zone]
|
|
43
|
+
: _resolveTzName(timezone_1.TIME_ZONES[zone]?.offset);
|
|
31
44
|
}
|
|
32
45
|
};
|
|
33
|
-
const
|
|
46
|
+
const TZ_ID_MAP = new Map(Object.entries(timezone_1.TIME_ZONE_IDS).reduce((acc, [id, { offset }]) => {
|
|
34
47
|
const arr = acc.get(offset) ?? [];
|
|
35
48
|
arr.push(id);
|
|
36
49
|
acc.set(offset, arr);
|
|
37
50
|
return acc;
|
|
38
51
|
}, new Map()));
|
|
39
52
|
const _getTimeZoneId = (utc) => {
|
|
40
|
-
const tzIds =
|
|
53
|
+
const tzIds = TZ_ID_MAP.get(utc);
|
|
41
54
|
if (!tzIds || tzIds?.length === 0)
|
|
42
55
|
return undefined;
|
|
43
56
|
if (tzIds?.length === 1)
|
|
@@ -59,51 +72,72 @@ const timeZonePlugin = (ChronosClass) => {
|
|
|
59
72
|
offset = zone in timezone_1.TIME_ZONES ? timezone_1.TIME_ZONES[zone].offset : timezone_1.TIME_ZONES['UTC'].offset;
|
|
60
73
|
tzId = _getTimeZoneId(offset) || offset;
|
|
61
74
|
}
|
|
62
|
-
const
|
|
75
|
+
const $zone = zone || offset;
|
|
76
|
+
const tzName = _getTimeZoneName($zone) ?? offset;
|
|
63
77
|
const targetOffset = (0, utils_1.extractMinutesFromUTC)(offset);
|
|
64
78
|
const previousOffset = this.getTimeZoneOffsetMinutes();
|
|
65
79
|
const relativeOffset = targetOffset - previousOffset;
|
|
66
80
|
const adjustedTime = new Date($Date(this).getTime() + relativeOffset * 60 * 1000);
|
|
67
81
|
const instance = new ChronosClass(adjustedTime);
|
|
68
|
-
return withOrigin(instance, `timeZone`, offset, tzName, tzId, zone);
|
|
82
|
+
return withOrigin(instance, `timeZone`, offset, tzName, tzId, $zone);
|
|
69
83
|
};
|
|
70
84
|
ChronosClass.prototype.getTimeZoneName = function (utc) {
|
|
71
85
|
const UTC = utc || this.utcOffset;
|
|
72
86
|
return _getTimeZoneName(utc || this?.$tzTracker || this.utcOffset) ?? UTC;
|
|
73
87
|
};
|
|
74
|
-
const
|
|
88
|
+
const TZ_ABBR_CACHE = new Map();
|
|
89
|
+
const _abbreviate = (name) => {
|
|
90
|
+
return name
|
|
91
|
+
.split(/\s+/)
|
|
92
|
+
.map((w) => w[0])
|
|
93
|
+
.join('')
|
|
94
|
+
.replace(/\W/g, '');
|
|
95
|
+
};
|
|
75
96
|
ChronosClass.prototype.getTimeZoneNameShort = function (utc) {
|
|
76
97
|
const tracker = this?.$tzTracker;
|
|
98
|
+
const UTC = utc || this.utcOffset;
|
|
99
|
+
const tzMapKey = utc || tracker || this.utcOffset;
|
|
100
|
+
if (_isGMT(tzMapKey))
|
|
101
|
+
return 'GMT';
|
|
77
102
|
if (!utc && tracker && tracker in timezone_1.TIME_ZONES)
|
|
78
103
|
return tracker;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
.
|
|
89
|
-
|
|
104
|
+
if ((0, guards_1.isValidUTCOffset)(tzMapKey)) {
|
|
105
|
+
if (TZ_ABBR_CACHE.has(tzMapKey))
|
|
106
|
+
return TZ_ABBR_CACHE.get(tzMapKey);
|
|
107
|
+
if (TZ_NAME_ABBR_MAP.has(tzMapKey)) {
|
|
108
|
+
return TZ_NAME_ABBR_MAP.get(tzMapKey)?.tzAbbr;
|
|
109
|
+
}
|
|
110
|
+
const tzName = _resolveTzName(tzMapKey);
|
|
111
|
+
if (tzName) {
|
|
112
|
+
const tzAbbr = _abbreviate(tzName);
|
|
113
|
+
TZ_ABBR_CACHE.set(tzMapKey, tzAbbr);
|
|
114
|
+
return tzAbbr;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const zone = _getTimeZoneName(tzMapKey) ?? UTC;
|
|
118
|
+
if (TZ_ABBR_CACHE.has(`name-${zone}`))
|
|
119
|
+
return TZ_ABBR_CACHE.get(zone);
|
|
120
|
+
const customAbbr = (0, guards_1.isValidUTCOffset)(zone) || (0, guards_1.isValidTimeZoneId)(zone) ? zone : _abbreviate(zone);
|
|
121
|
+
TZ_ABBR_CACHE.set(`name-${zone}`, customAbbr);
|
|
90
122
|
return customAbbr;
|
|
91
123
|
};
|
|
124
|
+
ChronosClass.prototype.getTimeZoneNameAbbr = function (utc) {
|
|
125
|
+
return this.getTimeZoneNameShort(utc);
|
|
126
|
+
};
|
|
92
127
|
ChronosClass.prototype.toString = function () {
|
|
93
128
|
const offset = this.utcOffset;
|
|
129
|
+
const search = /GMT[+-]\d{4}\s+\([^)]+\)/;
|
|
94
130
|
switch (this.origin) {
|
|
95
131
|
case 'timeZone': {
|
|
96
132
|
const gmt = offset.replace('UTC', 'GMT').replace(':', '');
|
|
97
133
|
const label = this.getTimeZoneName();
|
|
98
|
-
return $Date(this)
|
|
99
|
-
.toString()
|
|
100
|
-
.replace(/GMT[+-]\d{4}\s+\([^)]+\)/, `${gmt} (${label})`);
|
|
134
|
+
return $Date(this).toString().replace(search, `${gmt} (${label})`);
|
|
101
135
|
}
|
|
102
136
|
case 'toUTC':
|
|
103
137
|
case 'utc': {
|
|
104
138
|
return $Date(this)
|
|
105
139
|
.toString()
|
|
106
|
-
.replace(
|
|
140
|
+
.replace(search, `GMT+0000 (Coordinated Universal Time)`);
|
|
107
141
|
}
|
|
108
142
|
default:
|
|
109
143
|
return $Date(this).toString();
|
|
@@ -251,7 +251,7 @@ exports.TIME_ZONES = Object.freeze({
|
|
|
251
251
|
offset: 'UTC+07:00',
|
|
252
252
|
},
|
|
253
253
|
DDUT: {
|
|
254
|
-
tzName: "Dumont d'Urville Time (in French
|
|
254
|
+
tzName: "Dumont d'Urville Time (Antarctic Station in French)",
|
|
255
255
|
offset: 'UTC+10:00',
|
|
256
256
|
},
|
|
257
257
|
DFT: {
|
|
@@ -399,7 +399,7 @@ exports.TIME_ZONES = Object.freeze({
|
|
|
399
399
|
offset: 'UTC+07:00',
|
|
400
400
|
},
|
|
401
401
|
IDLW: {
|
|
402
|
-
tzName: 'International Date Line West
|
|
402
|
+
tzName: 'International Date Line West',
|
|
403
403
|
offset: 'UTC-12:00',
|
|
404
404
|
},
|
|
405
405
|
IDT: {
|
|
@@ -892,7 +892,7 @@ exports.TIME_ZONE_LABELS = Object.freeze({
|
|
|
892
892
|
'UTC+10:30': 'Lord Howe Standard Time',
|
|
893
893
|
'UTC+11:00': 'Central Pacific Standard Time',
|
|
894
894
|
'UTC+12:00': 'New Zealand Standard Time',
|
|
895
|
-
'UTC+12:45': 'Chatham
|
|
895
|
+
'UTC+12:45': 'Chatham Standard Time',
|
|
896
896
|
'UTC+13:00': 'Phoenix Island Time',
|
|
897
897
|
'UTC+14:00': 'Line Islands Time',
|
|
898
898
|
});
|
|
@@ -17,7 +17,7 @@ import type { $UTCOffset, ChronosInput, ChronosInternals, ChronosMethods, Chrono
|
|
|
17
17
|
* **It also accepts number values as following:**
|
|
18
18
|
* - **`year, month, date, hours, minutes, seconds, milliseconds`**: Individual components of a date-time to construct a `Chronos` instance.
|
|
19
19
|
* - **`year`**: A number representing the year. If the year is between 0 and 99, it will be assumed to be the year 1900 + the provided year.
|
|
20
|
-
* - **`month`**: A number between 1 and 12 representing the month (1 for January, 12 for December).
|
|
20
|
+
* - **`month`**: A number between 1 and 12 representing the month (1 for January, 12 for December).
|
|
21
21
|
* - **`date`**: A number between 1 and 31 representing the day of the month.
|
|
22
22
|
* - **`hours`**: A number between 0 and 23 representing the hour of the day.
|
|
23
23
|
* - **`minutes`**: A number between 0 and 59 representing the minutes past the hour.
|
|
@@ -198,13 +198,13 @@ export declare class Chronos {
|
|
|
198
198
|
get lastDateOfMonth(): NumberRange<28, 31>;
|
|
199
199
|
/** @instance Returns a debug-friendly string for `console.log` or `util.inspect`. */
|
|
200
200
|
inspect(): string;
|
|
201
|
-
/** @instance Enables JSON.stringify
|
|
201
|
+
/** @instance Enables `JSON.stringify` to show readable output. Calls {@link toLocalISOString} method. */
|
|
202
202
|
toJSON(): string;
|
|
203
|
-
/** @instance Enables arithmetic and comparison operations (e.g.,
|
|
203
|
+
/** @instance Enables arithmetic and comparison operations (e.g., `+new Chronos()`). Calls {@link getTimeStamp} method. */
|
|
204
204
|
valueOf(): number;
|
|
205
|
-
/** @instance Clones and returns
|
|
205
|
+
/** @instance Clones and returns exactly same `Chronos` instance. */
|
|
206
206
|
clone(): Chronos;
|
|
207
|
-
/** @instance Gets the native `Date` instance
|
|
207
|
+
/** @instance Gets the native `Date` instance of the current `Chronos`. */
|
|
208
208
|
toDate(): Date;
|
|
209
209
|
/** @instance Returns a string representation of a date. */
|
|
210
210
|
toString(): string;
|
|
@@ -320,11 +320,11 @@ export declare class Chronos {
|
|
|
320
320
|
* @returns `true` if the year is a leap year, `false` otherwise.
|
|
321
321
|
*/
|
|
322
322
|
isLeapYear(year?: number): boolean;
|
|
323
|
-
/** @instance Checks if another date is exactly equal to this one */
|
|
323
|
+
/** @instance Checks if another date is exactly equal to this one. */
|
|
324
324
|
isEqual(other: ChronosInput): boolean;
|
|
325
|
-
/** @instance Checks if another date is exactly equal to or before this one */
|
|
325
|
+
/** @instance Checks if another date is exactly equal to or before this one. */
|
|
326
326
|
isEqualOrBefore(other: ChronosInput): boolean;
|
|
327
|
-
/** @instance Checks if another date is exactly equal to or after this one */
|
|
327
|
+
/** @instance Checks if another date is exactly equal to or after this one. */
|
|
328
328
|
isEqualOrAfter(other: ChronosInput): boolean;
|
|
329
329
|
/**
|
|
330
330
|
* @instance Checks if another date is the same as this one in a specific unit.
|
|
@@ -489,7 +489,7 @@ export declare class Chronos {
|
|
|
489
489
|
* - `Q3`: July to September
|
|
490
490
|
* - `Q4`: October to December
|
|
491
491
|
*
|
|
492
|
-
* This method strictly uses the **calendar year**. For fiscal quarters, use
|
|
492
|
+
* This method strictly uses the **calendar year**. For fiscal quarters, use {@link toFiscalQuarter} instead.
|
|
493
493
|
*
|
|
494
494
|
* @example
|
|
495
495
|
* new Chronos('2025-02-14').toQuarter(); // 1
|
|
@@ -752,12 +752,12 @@ export declare class Chronos {
|
|
|
752
752
|
*/
|
|
753
753
|
static getDatesForDay(day: WeekDay, options?: DateRangeOptions): string[];
|
|
754
754
|
/**
|
|
755
|
-
* @static Returns earliest Chronos
|
|
755
|
+
* @static Returns earliest Chronos.
|
|
756
756
|
* @param dates Date inputs.
|
|
757
757
|
*/
|
|
758
758
|
static min(...dates: ChronosInput[]): Chronos;
|
|
759
759
|
/**
|
|
760
|
-
* @static Returns latest Chronos
|
|
760
|
+
* @static Returns latest Chronos.
|
|
761
761
|
* @param dates Date inputs.
|
|
762
762
|
*/
|
|
763
763
|
static max(...dates: ChronosInput[]): Chronos;
|
|
@@ -107,13 +107,13 @@ declare module '../Chronos' {
|
|
|
107
107
|
*/
|
|
108
108
|
isBusinessHour(options?: BusinessOptionsWeekends): boolean;
|
|
109
109
|
/**
|
|
110
|
-
* @instance Returns the academic year based on a typical start in July and end in June
|
|
110
|
+
* @instance Returns the academic year based on a typical start in `July` and end in `June`.
|
|
111
111
|
* @returns The academic year in format `YYYY-YYYY`.
|
|
112
112
|
*/
|
|
113
113
|
toAcademicYear(): AcademicYear;
|
|
114
114
|
/**
|
|
115
115
|
* @instance Returns the fiscal quarter based on custom fiscal year start (defaults to July).
|
|
116
|
-
* @param startMonth - The fiscal year start month (1-12), default is July (7).
|
|
116
|
+
* @param startMonth - The fiscal year start month (1-12), default is July (`7`).
|
|
117
117
|
* @returns The fiscal quarter (1-4).
|
|
118
118
|
*/
|
|
119
119
|
toFiscalQuarter(startMonth?: NumberRange<1, 12>): Quarter;
|
|
@@ -4,6 +4,9 @@ declare module '../Chronos' {
|
|
|
4
4
|
interface Chronos {
|
|
5
5
|
/**
|
|
6
6
|
* @instance Returns the full time duration breakdown between current input (start) and another time (to) as {@link TimeDuration} object.
|
|
7
|
+
*
|
|
8
|
+
* @remarks This method calculates the elapsed time difference (excludes the end day), if you need an inclusive calendar-style difference (counting both start and end days), adjust one day manually before calling `duration()`.
|
|
9
|
+
*
|
|
7
10
|
* @param toTime The time to compare with. Defaults to `now`.
|
|
8
11
|
* @param absolute If true, returns all values as positive numbers. Defaults to `true`.
|
|
9
12
|
* @returns An object of time units: `years`, `months`, `days`, `hours`, `minutes`, `seconds`, `milliseconds` ({@link TimeDuration}).
|
|
@@ -11,6 +14,9 @@ declare module '../Chronos' {
|
|
|
11
14
|
duration(toTime?: ChronosInput, absolute?: boolean): TimeDuration;
|
|
12
15
|
/**
|
|
13
16
|
* @instance Returns a human-readable formatted duration string between the current instance (start) and another time (to).
|
|
17
|
+
*
|
|
18
|
+
* @remarks This method calculates the elapsed time difference (excludes the end day), if you need an inclusive calendar-style difference (counting both start and end days), adjust one day manually before calling `durationString()`.
|
|
19
|
+
*
|
|
14
20
|
* @param options {@link DurationOptions} to format duration string, including the time to compare with.
|
|
15
21
|
* @returns A formatted duration string, e.g. `"2 hours, 5 minutes"` or `"2h 5m"`.
|
|
16
22
|
*/
|
|
@@ -34,23 +34,20 @@ declare module '../Chronos' {
|
|
|
34
34
|
/**
|
|
35
35
|
* @instance Returns the current time zone name as a full descriptive string (e.g. `"Bangladesh Standard Time"`).
|
|
36
36
|
*
|
|
37
|
-
* @param utc Optional UTC offset in `"UTC+06:00"` format. When passed, it bypasses the current time zone offset.
|
|
38
|
-
* @returns Time zone name in full descriptive string or UTC offset if it is not a valid time zone.
|
|
39
|
-
*
|
|
40
37
|
* @remarks
|
|
41
38
|
* - This method uses a predefined mapping of UTC offsets to time zone names.
|
|
42
39
|
* - If multiple time zones share the same UTC offset, it returns the **first match** from the predefined list.
|
|
43
40
|
* - If no match is found (which is rare), it falls back to returning the UTC offset (e.g. `"UTC+06:00"`).
|
|
44
41
|
* - To retrieve the local system's native time zone name (or its identifier if the name is unavailable), use the {@link $getNativeTimeZone} instance method.
|
|
45
42
|
* - To retrieve the local system's native time zone identifier, use the {@link $getNativeTimeZoneId} instance method.
|
|
43
|
+
*
|
|
44
|
+
* @param utc Optional UTC offset in `"UTC+06:00"` format. When passed, it bypasses the current time zone offset.
|
|
45
|
+
* @returns Time zone name in full descriptive string or UTC offset if it is not a valid time zone.
|
|
46
46
|
*/
|
|
47
47
|
getTimeZoneName(utc?: UTCOffset): LooseLiteral<TimeZoneName | UTCOffset>;
|
|
48
48
|
/**
|
|
49
49
|
* @instance Returns the current time zone abbreviation (e.g. `"BST"` for `Bangladesh Standard Time`).
|
|
50
50
|
*
|
|
51
|
-
* @param utc Optional UTC offset in `"UTC+06:00"` format. When passed, it bypasses the current time zone offset.
|
|
52
|
-
* @returns Time zone name in full descriptive string or UTC offset if it is not a valid time zone.
|
|
53
|
-
*
|
|
54
51
|
* @remarks
|
|
55
52
|
* - This method uses a predefined mapping of UTC offsets to abbreviated time zone codes.
|
|
56
53
|
* - If multiple time zones share the same UTC offset, it returns the **first abbreviation** from the list.
|
|
@@ -58,8 +55,20 @@ declare module '../Chronos' {
|
|
|
58
55
|
* - If no match is found (for unlisted or fictional utc offset), it returns the UTC offset (e.g. `"UTC+06:00"`).
|
|
59
56
|
* - To retrieve the local system's native time zone name (or its identifier if the name is unavailable), use the {@link $getNativeTimeZone} instance method.
|
|
60
57
|
* - To retrieve the local system's native time zone identifier, use the {@link $getNativeTimeZoneId} instance method.
|
|
58
|
+
*
|
|
59
|
+
* @param utc Optional UTC offset in `"UTC+06:00"` format. When passed, it bypasses the current time zone offset.
|
|
60
|
+
* @returns Time zone name in full descriptive string or UTC offset if it is not a valid time zone.
|
|
61
61
|
*/
|
|
62
62
|
getTimeZoneNameShort(utc?: UTCOffset): LooseLiteral<TimeZone | UTCOffset>;
|
|
63
|
+
/**
|
|
64
|
+
* @instance Returns the current time zone abbreviation (e.g. `"BST"` for `Bangladesh Standard Time`).
|
|
65
|
+
*
|
|
66
|
+
* @remarks This method is an alias for {@link getTimeZoneNameShort}.
|
|
67
|
+
*
|
|
68
|
+
* @param utc Optional UTC offset in `"UTC+06:00"` format. When passed, it bypasses the current time zone offset.
|
|
69
|
+
* @returns Time zone name in full descriptive string or UTC offset if it is not a valid time zone.
|
|
70
|
+
*/
|
|
71
|
+
getTimeZoneNameAbbr(utc?: UTCOffset): LooseLiteral<TimeZone | UTCOffset>;
|
|
63
72
|
}
|
|
64
73
|
}
|
|
65
74
|
/** * Plugin to inject `timeZone` related methods */
|
|
@@ -249,7 +249,7 @@ export declare const TIME_ZONES: Readonly<{
|
|
|
249
249
|
readonly offset: "UTC+07:00";
|
|
250
250
|
};
|
|
251
251
|
readonly DDUT: {
|
|
252
|
-
readonly tzName: "Dumont d'Urville Time (in French
|
|
252
|
+
readonly tzName: "Dumont d'Urville Time (Antarctic Station in French)";
|
|
253
253
|
readonly offset: "UTC+10:00";
|
|
254
254
|
};
|
|
255
255
|
readonly DFT: {
|
|
@@ -397,7 +397,7 @@ export declare const TIME_ZONES: Readonly<{
|
|
|
397
397
|
readonly offset: "UTC+07:00";
|
|
398
398
|
};
|
|
399
399
|
readonly IDLW: {
|
|
400
|
-
readonly tzName: "International Date Line West
|
|
400
|
+
readonly tzName: "International Date Line West";
|
|
401
401
|
readonly offset: "UTC-12:00";
|
|
402
402
|
};
|
|
403
403
|
readonly IDT: {
|
|
@@ -891,7 +891,7 @@ export declare const TIME_ZONE_LABELS: Readonly<{
|
|
|
891
891
|
readonly 'UTC+10:30': "Lord Howe Standard Time";
|
|
892
892
|
readonly 'UTC+11:00': "Central Pacific Standard Time";
|
|
893
893
|
readonly 'UTC+12:00': "New Zealand Standard Time";
|
|
894
|
-
readonly 'UTC+12:45': "Chatham
|
|
894
|
+
readonly 'UTC+12:45': "Chatham Standard Time";
|
|
895
895
|
readonly 'UTC+13:00': "Phoenix Island Time";
|
|
896
896
|
readonly 'UTC+14:00': "Line Islands Time";
|
|
897
897
|
}>;
|
package/dist/dts/date/types.d.ts
CHANGED
|
@@ -214,6 +214,7 @@ export type ChronosMethods = $InstanceMethods | $StaticMethods | $PluginMethods;
|
|
|
214
214
|
export type ChronosInput = number | string | Date | Chronos;
|
|
215
215
|
/** Represents key of `ChronosStatics` (each static method and property) */
|
|
216
216
|
export type ChronosStaticKey = keyof ChronosStatics;
|
|
217
|
+
/** Key of {@link TIME_ZONE_LABELS} ({@link UTCOffset}) */
|
|
217
218
|
export type $TZLabelKey = keyof typeof TIME_ZONE_LABELS;
|
|
218
219
|
/** Abbreviated time-zone names (from {@link https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations time zone abbreviations on Wikipedia}) */
|
|
219
220
|
export type TimeZone = keyof typeof TIME_ZONES;
|
package/dist/esm/date/Chronos.js
CHANGED
|
@@ -281,7 +281,7 @@ export class Chronos {
|
|
|
281
281
|
return this.getTimeStamp();
|
|
282
282
|
}
|
|
283
283
|
clone() {
|
|
284
|
-
return new _a(this.#date).#withOrigin(this.#ORIGIN);
|
|
284
|
+
return new _a(this.#date).#withOrigin(this.#ORIGIN, this.#offset, this.timeZoneName, this.timeZoneId, this.$tzTracker);
|
|
285
285
|
}
|
|
286
286
|
toDate() {
|
|
287
287
|
switch (this.#ORIGIN) {
|
|
@@ -4,6 +4,13 @@ import { TIME_ZONES, TIME_ZONE_IDS, TIME_ZONE_LABELS } from '../timezone.js';
|
|
|
4
4
|
import { extractMinutesFromUTC } from '../utils.js';
|
|
5
5
|
export const timeZonePlugin = (ChronosClass) => {
|
|
6
6
|
const { internalDate: $Date, withOrigin } = ChronosClass[INTERNALS];
|
|
7
|
+
const _isGMT = (factor) => {
|
|
8
|
+
return factor === 'UTC+00:00' || factor === 'UTC-00:00';
|
|
9
|
+
};
|
|
10
|
+
const TZ_NAME_ABBR_MAP = new Map(Object.entries(TIME_ZONES).map(([tzAbbr, { offset, tzName }]) => [
|
|
11
|
+
offset,
|
|
12
|
+
{ tzAbbr, tzName },
|
|
13
|
+
]));
|
|
7
14
|
const _isLabelKey = (offset) => {
|
|
8
15
|
return offset in TIME_ZONE_LABELS;
|
|
9
16
|
};
|
|
@@ -14,8 +21,14 @@ export const timeZonePlugin = (ChronosClass) => {
|
|
|
14
21
|
return undefined;
|
|
15
22
|
};
|
|
16
23
|
const _getTimeZoneName = (zone) => {
|
|
24
|
+
if (_isGMT(zone))
|
|
25
|
+
return 'Greenwich Mean Time';
|
|
17
26
|
if (isValidUTCOffset(zone)) {
|
|
18
|
-
|
|
27
|
+
const tzName = _resolveTzName(zone);
|
|
28
|
+
if (!tzName && TZ_NAME_ABBR_MAP.has(zone)) {
|
|
29
|
+
return TZ_NAME_ABBR_MAP.get(zone)?.tzName;
|
|
30
|
+
}
|
|
31
|
+
return tzName;
|
|
19
32
|
}
|
|
20
33
|
else if (isValidTimeZoneId(zone)) {
|
|
21
34
|
const record = TIME_ZONE_IDS[zone];
|
|
@@ -24,17 +37,17 @@ export const timeZonePlugin = (ChronosClass) => {
|
|
|
24
37
|
else {
|
|
25
38
|
return zone in TIME_ZONES ?
|
|
26
39
|
TIME_ZONES[zone].tzName
|
|
27
|
-
: _resolveTzName(TIME_ZONES[zone]
|
|
40
|
+
: _resolveTzName(TIME_ZONES[zone]?.offset);
|
|
28
41
|
}
|
|
29
42
|
};
|
|
30
|
-
const
|
|
43
|
+
const TZ_ID_MAP = new Map(Object.entries(TIME_ZONE_IDS).reduce((acc, [id, { offset }]) => {
|
|
31
44
|
const arr = acc.get(offset) ?? [];
|
|
32
45
|
arr.push(id);
|
|
33
46
|
acc.set(offset, arr);
|
|
34
47
|
return acc;
|
|
35
48
|
}, new Map()));
|
|
36
49
|
const _getTimeZoneId = (utc) => {
|
|
37
|
-
const tzIds =
|
|
50
|
+
const tzIds = TZ_ID_MAP.get(utc);
|
|
38
51
|
if (!tzIds || tzIds?.length === 0)
|
|
39
52
|
return undefined;
|
|
40
53
|
if (tzIds?.length === 1)
|
|
@@ -56,51 +69,72 @@ export const timeZonePlugin = (ChronosClass) => {
|
|
|
56
69
|
offset = zone in TIME_ZONES ? TIME_ZONES[zone].offset : TIME_ZONES['UTC'].offset;
|
|
57
70
|
tzId = _getTimeZoneId(offset) || offset;
|
|
58
71
|
}
|
|
59
|
-
const
|
|
72
|
+
const $zone = zone || offset;
|
|
73
|
+
const tzName = _getTimeZoneName($zone) ?? offset;
|
|
60
74
|
const targetOffset = extractMinutesFromUTC(offset);
|
|
61
75
|
const previousOffset = this.getTimeZoneOffsetMinutes();
|
|
62
76
|
const relativeOffset = targetOffset - previousOffset;
|
|
63
77
|
const adjustedTime = new Date($Date(this).getTime() + relativeOffset * 60 * 1000);
|
|
64
78
|
const instance = new ChronosClass(adjustedTime);
|
|
65
|
-
return withOrigin(instance, `timeZone`, offset, tzName, tzId, zone);
|
|
79
|
+
return withOrigin(instance, `timeZone`, offset, tzName, tzId, $zone);
|
|
66
80
|
};
|
|
67
81
|
ChronosClass.prototype.getTimeZoneName = function (utc) {
|
|
68
82
|
const UTC = utc || this.utcOffset;
|
|
69
83
|
return _getTimeZoneName(utc || this?.$tzTracker || this.utcOffset) ?? UTC;
|
|
70
84
|
};
|
|
71
|
-
const
|
|
85
|
+
const TZ_ABBR_CACHE = new Map();
|
|
86
|
+
const _abbreviate = (name) => {
|
|
87
|
+
return name
|
|
88
|
+
.split(/\s+/)
|
|
89
|
+
.map((w) => w[0])
|
|
90
|
+
.join('')
|
|
91
|
+
.replace(/\W/g, '');
|
|
92
|
+
};
|
|
72
93
|
ChronosClass.prototype.getTimeZoneNameShort = function (utc) {
|
|
73
94
|
const tracker = this?.$tzTracker;
|
|
95
|
+
const UTC = utc || this.utcOffset;
|
|
96
|
+
const tzMapKey = utc || tracker || this.utcOffset;
|
|
97
|
+
if (_isGMT(tzMapKey))
|
|
98
|
+
return 'GMT';
|
|
74
99
|
if (!utc && tracker && tracker in TIME_ZONES)
|
|
75
100
|
return tracker;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
.
|
|
86
|
-
|
|
101
|
+
if (isValidUTCOffset(tzMapKey)) {
|
|
102
|
+
if (TZ_ABBR_CACHE.has(tzMapKey))
|
|
103
|
+
return TZ_ABBR_CACHE.get(tzMapKey);
|
|
104
|
+
if (TZ_NAME_ABBR_MAP.has(tzMapKey)) {
|
|
105
|
+
return TZ_NAME_ABBR_MAP.get(tzMapKey)?.tzAbbr;
|
|
106
|
+
}
|
|
107
|
+
const tzName = _resolveTzName(tzMapKey);
|
|
108
|
+
if (tzName) {
|
|
109
|
+
const tzAbbr = _abbreviate(tzName);
|
|
110
|
+
TZ_ABBR_CACHE.set(tzMapKey, tzAbbr);
|
|
111
|
+
return tzAbbr;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const zone = _getTimeZoneName(tzMapKey) ?? UTC;
|
|
115
|
+
if (TZ_ABBR_CACHE.has(`name-${zone}`))
|
|
116
|
+
return TZ_ABBR_CACHE.get(zone);
|
|
117
|
+
const customAbbr = isValidUTCOffset(zone) || isValidTimeZoneId(zone) ? zone : _abbreviate(zone);
|
|
118
|
+
TZ_ABBR_CACHE.set(`name-${zone}`, customAbbr);
|
|
87
119
|
return customAbbr;
|
|
88
120
|
};
|
|
121
|
+
ChronosClass.prototype.getTimeZoneNameAbbr = function (utc) {
|
|
122
|
+
return this.getTimeZoneNameShort(utc);
|
|
123
|
+
};
|
|
89
124
|
ChronosClass.prototype.toString = function () {
|
|
90
125
|
const offset = this.utcOffset;
|
|
126
|
+
const search = /GMT[+-]\d{4}\s+\([^)]+\)/;
|
|
91
127
|
switch (this.origin) {
|
|
92
128
|
case 'timeZone': {
|
|
93
129
|
const gmt = offset.replace('UTC', 'GMT').replace(':', '');
|
|
94
130
|
const label = this.getTimeZoneName();
|
|
95
|
-
return $Date(this)
|
|
96
|
-
.toString()
|
|
97
|
-
.replace(/GMT[+-]\d{4}\s+\([^)]+\)/, `${gmt} (${label})`);
|
|
131
|
+
return $Date(this).toString().replace(search, `${gmt} (${label})`);
|
|
98
132
|
}
|
|
99
133
|
case 'toUTC':
|
|
100
134
|
case 'utc': {
|
|
101
135
|
return $Date(this)
|
|
102
136
|
.toString()
|
|
103
|
-
.replace(
|
|
137
|
+
.replace(search, `GMT+0000 (Coordinated Universal Time)`);
|
|
104
138
|
}
|
|
105
139
|
default:
|
|
106
140
|
return $Date(this).toString();
|
|
@@ -248,7 +248,7 @@ export const TIME_ZONES = Object.freeze({
|
|
|
248
248
|
offset: 'UTC+07:00',
|
|
249
249
|
},
|
|
250
250
|
DDUT: {
|
|
251
|
-
tzName: "Dumont d'Urville Time (in French
|
|
251
|
+
tzName: "Dumont d'Urville Time (Antarctic Station in French)",
|
|
252
252
|
offset: 'UTC+10:00',
|
|
253
253
|
},
|
|
254
254
|
DFT: {
|
|
@@ -396,7 +396,7 @@ export const TIME_ZONES = Object.freeze({
|
|
|
396
396
|
offset: 'UTC+07:00',
|
|
397
397
|
},
|
|
398
398
|
IDLW: {
|
|
399
|
-
tzName: 'International Date Line West
|
|
399
|
+
tzName: 'International Date Line West',
|
|
400
400
|
offset: 'UTC-12:00',
|
|
401
401
|
},
|
|
402
402
|
IDT: {
|
|
@@ -889,7 +889,7 @@ export const TIME_ZONE_LABELS = Object.freeze({
|
|
|
889
889
|
'UTC+10:30': 'Lord Howe Standard Time',
|
|
890
890
|
'UTC+11:00': 'Central Pacific Standard Time',
|
|
891
891
|
'UTC+12:00': 'New Zealand Standard Time',
|
|
892
|
-
'UTC+12:45': 'Chatham
|
|
892
|
+
'UTC+12:45': 'Chatham Standard Time',
|
|
893
893
|
'UTC+13:00': 'Phoenix Island Time',
|
|
894
894
|
'UTC+14:00': 'Line Islands Time',
|
|
895
895
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nhb-toolbox",
|
|
3
|
-
"version": "4.26.
|
|
3
|
+
"version": "4.26.30",
|
|
4
4
|
"description": "A versatile collection of smart, efficient, and reusable utility functions, classes and types for everyday development needs.",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"@eslint/js": "^9.39.1",
|
|
43
43
|
"@types/jest": "^30.0.0",
|
|
44
44
|
"@types/node": "^24.10.0",
|
|
45
|
-
"@typescript-eslint/eslint-plugin": "^8.46.
|
|
46
|
-
"@typescript-eslint/parser": "^8.46.
|
|
45
|
+
"@typescript-eslint/eslint-plugin": "^8.46.4",
|
|
46
|
+
"@typescript-eslint/parser": "^8.46.4",
|
|
47
47
|
"eslint": "^9.39.1",
|
|
48
48
|
"eslint-config-prettier": "^10.1.8",
|
|
49
49
|
"eslint-plugin-prettier": "^5.5.4",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"ts-jest": "^29.4.5",
|
|
57
57
|
"ts-node": "^10.9.2",
|
|
58
58
|
"typescript": "^5.9.3",
|
|
59
|
-
"typescript-eslint": "^8.46.
|
|
59
|
+
"typescript-eslint": "^8.46.4"
|
|
60
60
|
},
|
|
61
61
|
"keywords": [
|
|
62
62
|
"toolbox",
|