nhb-toolbox 4.26.1 → 4.26.20
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 +32 -0
- package/README.md +2 -2
- package/dist/cjs/date/Chronos.js +21 -110
- package/dist/cjs/date/constants.js +2 -2
- package/dist/cjs/date/guards.js +3 -1
- package/dist/cjs/date/plugins/businessPlugin.js +1 -1
- package/dist/cjs/date/plugins/dayPartPlugin.js +1 -1
- package/dist/cjs/date/plugins/durationPlugin.js +105 -0
- package/dist/cjs/date/plugins/fromNowPlugin.js +3 -3
- package/dist/cjs/date/plugins/relativeTimePlugin.js +8 -9
- package/dist/cjs/date/plugins/roundPlugin.js +4 -4
- package/dist/cjs/date/plugins/timeZonePlugin.js +63 -36
- package/dist/cjs/date/timezone.js +3242 -743
- package/dist/dts/date/Chronos.d.ts +22 -37
- package/dist/dts/date/constants.d.ts +1 -1
- package/dist/dts/date/guards.d.ts +3 -3
- package/dist/dts/date/plugins/durationPlugin.d.ts +22 -0
- package/dist/dts/date/plugins/relativeTimePlugin.d.ts +15 -11
- package/dist/dts/date/plugins/timeZonePlugin.d.ts +33 -8
- package/dist/dts/date/timezone.d.ts +3288 -878
- package/dist/dts/date/types.d.ts +23 -17
- package/dist/dts/date/utils.d.ts +4 -4
- package/dist/esm/date/Chronos.js +19 -109
- package/dist/esm/date/constants.js +1 -1
- package/dist/esm/date/guards.js +3 -1
- package/dist/esm/date/plugins/businessPlugin.js +1 -1
- package/dist/esm/date/plugins/dayPartPlugin.js +2 -2
- package/dist/esm/date/plugins/durationPlugin.js +101 -0
- package/dist/esm/date/plugins/fromNowPlugin.js +3 -3
- package/dist/esm/date/plugins/relativeTimePlugin.js +8 -9
- package/dist/esm/date/plugins/roundPlugin.js +4 -4
- package/dist/esm/date/plugins/timeZonePlugin.js +64 -37
- package/dist/esm/date/timezone.js +3242 -743
- package/package.json +9 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,38 @@ All notable changes to the package will be documented here.
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
## [4.26.20] - 2025-11-10
|
|
10
|
+
|
|
11
|
+
### 🕧 Updates in Chronos
|
|
12
|
+
|
|
13
|
+
- **Moved** `duration` and `durationString` methods to `Chronos` *plugin system*, usable via `durationPlugin`.
|
|
14
|
+
- **Optimized** related *plugins* where *internal private methods* are used.
|
|
15
|
+
- **Updated** *tsdoc* for `relativeTimePlugin` methods.
|
|
16
|
+
|
|
17
|
+
## [4.26.10] - 2025-11-09
|
|
18
|
+
|
|
19
|
+
### 🕧 Updates in Chronos
|
|
20
|
+
|
|
21
|
+
- **Fixed** *timezone conversion issues* by updating `TIME_ZONE_IDS`, and `TIME_ZONES` constants:
|
|
22
|
+
- Now both the constants have similar *type definitions* and used with `as const` in the codebase.
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
// Example structure after unification
|
|
26
|
+
const TIME_ZONE_IDS: Record<string, { tzName: string; offset: UTCOffSet }> = {
|
|
27
|
+
'Asia/Dhaka': { tzName: 'Bangladesh Standard Time', offset: 'UTC+06:00' },
|
|
28
|
+
// ...
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const TIME_ZONES: Record<string, { tzName: string; offset: UTCOffSet }> = {
|
|
32
|
+
BST: { tzName: 'Bangladesh Standard Time', offset: 'UTC+06:00' },
|
|
33
|
+
// ...
|
|
34
|
+
};
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- **Added** new *protected property* `$tzTracker`. **Updated** `withOrigin` and `#withOrigin` methods.
|
|
38
|
+
- **Added** *3 overload signatures* and *internal caching mechanism* for `timeZonePlugin` methods.
|
|
39
|
+
- **Updated** *tsdoc* for some `Chronos` methods. **Created** new type `TimeZoneName` and *more*.
|
|
40
|
+
|
|
9
41
|
## [4.26.1] - 2025-11-08
|
|
10
42
|
|
|
11
43
|
- **Updated** *tsdoc* for some `Chronos` *methods* and *public properties*.
|
package/README.md
CHANGED
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
</a>
|
|
46
46
|
</p>
|
|
47
47
|
|
|
48
|
-
## TypeScript Utility Library
|
|
48
|
+
## JavaScript/TypeScript Utility Library
|
|
49
49
|
|
|
50
|
-
**NHB Toolbox** provides battle-tested utilities for professional TypeScript development. Carefully crafted to solve common challenges with elegant, production-ready solutions:
|
|
50
|
+
**NHB Toolbox** provides battle-tested utilities for professional JavaScript/TypeScript development. Carefully crafted to solve common challenges with elegant, production-ready solutions:
|
|
51
51
|
|
|
52
52
|
- **Helper Functions & Classes**: Reusable solutions for everyday tasks
|
|
53
53
|
- **Type Guards & Predicates**: Runtime safety with perfect type inference
|
package/dist/cjs/date/Chronos.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.Chronos = void 0;
|
|
4
|
+
exports.chronos = exports.Chronos = void 0;
|
|
5
5
|
const non_primitives_1 = require("../guards/non-primitives");
|
|
6
6
|
const primitives_1 = require("../guards/primitives");
|
|
7
7
|
const utilities_1 = require("../number/utilities");
|
|
@@ -20,8 +20,8 @@ class Chronos {
|
|
|
20
20
|
offset(instance) {
|
|
21
21
|
return instance.#offset;
|
|
22
22
|
},
|
|
23
|
-
withOrigin(instance, method, offset, tzName, tzId) {
|
|
24
|
-
return instance.#withOrigin(method, offset, tzName, tzId);
|
|
23
|
+
withOrigin(instance, method, offset, tzName, tzId, tzTracker) {
|
|
24
|
+
return instance.#withOrigin(method, offset, tzName, tzId, tzTracker);
|
|
25
25
|
},
|
|
26
26
|
toNewDate(instance, value) {
|
|
27
27
|
return instance.#toNewDate(value);
|
|
@@ -32,6 +32,7 @@ class Chronos {
|
|
|
32
32
|
utcOffset;
|
|
33
33
|
timeZoneName;
|
|
34
34
|
timeZoneId;
|
|
35
|
+
$tzTracker;
|
|
35
36
|
constructor(valueOrYear, month, date, hours, minutes, seconds, ms) {
|
|
36
37
|
if (typeof valueOrYear === 'number' && typeof month === 'number') {
|
|
37
38
|
this.#date = new Date(valueOrYear, month - 1, date ?? 1, hours ?? 0, minutes ?? 0, seconds ?? 0, ms ?? 0);
|
|
@@ -80,9 +81,9 @@ class Chronos {
|
|
|
80
81
|
case 'timeZone':
|
|
81
82
|
case 'toUTC':
|
|
82
83
|
case 'utc':
|
|
83
|
-
return string.replace(this
|
|
84
|
+
return string.replace(this.#isoTzRemoved(), replacement);
|
|
84
85
|
default:
|
|
85
|
-
return string.replace(this
|
|
86
|
+
return string.replace(this.#isoTzRemoved(true), replacement);
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
89
|
[Symbol.search](string) {
|
|
@@ -90,9 +91,9 @@ class Chronos {
|
|
|
90
91
|
case 'timeZone':
|
|
91
92
|
case 'toUTC':
|
|
92
93
|
case 'utc':
|
|
93
|
-
return string.indexOf(this
|
|
94
|
+
return string.indexOf(this.#isoTzRemoved());
|
|
94
95
|
default:
|
|
95
|
-
return string.indexOf(this
|
|
96
|
+
return string.indexOf(this.#isoTzRemoved(true));
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
99
|
[Symbol.split](string) {
|
|
@@ -100,9 +101,9 @@ class Chronos {
|
|
|
100
101
|
case 'timeZone':
|
|
101
102
|
case 'toUTC':
|
|
102
103
|
case 'utc':
|
|
103
|
-
return string.split(this
|
|
104
|
+
return string.split(this.#isoTzRemoved());
|
|
104
105
|
default:
|
|
105
|
-
return string.split(this
|
|
106
|
+
return string.split(this.#isoTzRemoved(true));
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
[Symbol.match](string) {
|
|
@@ -144,7 +145,7 @@ class Chronos {
|
|
|
144
145
|
}
|
|
145
146
|
return date;
|
|
146
147
|
}
|
|
147
|
-
#withOrigin(origin, offset, tzName, tzId) {
|
|
148
|
+
#withOrigin(origin, offset, tzName, tzId, tzTracker) {
|
|
148
149
|
const instance = new _a(this.#date);
|
|
149
150
|
instance.#ORIGIN = origin;
|
|
150
151
|
instance.origin = origin;
|
|
@@ -152,12 +153,12 @@ class Chronos {
|
|
|
152
153
|
instance.#offset = offset;
|
|
153
154
|
instance.utcOffset = offset;
|
|
154
155
|
}
|
|
155
|
-
if (tzName)
|
|
156
|
+
if (tzName)
|
|
156
157
|
instance.timeZoneName = tzName;
|
|
157
|
-
|
|
158
|
-
if (tzId) {
|
|
158
|
+
if (tzId)
|
|
159
159
|
instance.timeZoneId = tzId;
|
|
160
|
-
|
|
160
|
+
if (tzTracker)
|
|
161
|
+
instance.$tzTracker = tzTracker;
|
|
161
162
|
instance.native = instance.toDate();
|
|
162
163
|
return instance;
|
|
163
164
|
}
|
|
@@ -228,22 +229,10 @@ class Chronos {
|
|
|
228
229
|
const pad = (n, p = 2) => String(n).padStart(p, '0');
|
|
229
230
|
return `${this.year}-${pad(this.month + 1)}-${pad(this.date)}T${pad(this.hour)}:${pad(this.minute)}:${pad(this.second)}.${pad(this.millisecond, 3)}${this.getUTCOffset()}`;
|
|
230
231
|
}
|
|
231
|
-
#
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
for (const [key, value] of entries) {
|
|
236
|
-
if (value !== 0) {
|
|
237
|
-
updated[key] = value * -1;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
else if (absolute) {
|
|
242
|
-
for (const [key, value] of entries) {
|
|
243
|
-
updated[key] = Math.abs(value);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
return updated;
|
|
232
|
+
#isoTzRemoved(local = false) {
|
|
233
|
+
return local ?
|
|
234
|
+
this.toLocalISOString().replace(/\.\d+(Z|[+-]\d{2}:\d{2})?$/, '')
|
|
235
|
+
: this.toISOString().replace(/\.\d+(Z|[+-]\d{2}:\d{2})?$/, '');
|
|
247
236
|
}
|
|
248
237
|
get year() {
|
|
249
238
|
return this.#date.getFullYear();
|
|
@@ -754,86 +743,6 @@ class Chronos {
|
|
|
754
743
|
const localTime = new Date(this.#date.getTime() - offset * 60 * 1000);
|
|
755
744
|
return new _a(localTime).#withOrigin('toLocal');
|
|
756
745
|
}
|
|
757
|
-
duration(toTime, absolute = true) {
|
|
758
|
-
const now = this.#date;
|
|
759
|
-
const target = this.#toNewDate(toTime);
|
|
760
|
-
const isFuture = target > now;
|
|
761
|
-
const from = isFuture ? now : target;
|
|
762
|
-
const to = isFuture ? target : now;
|
|
763
|
-
const _getDiff = (suffix) => {
|
|
764
|
-
const method = ('get' + suffix);
|
|
765
|
-
return to[method]() - from[method]();
|
|
766
|
-
};
|
|
767
|
-
let years = _getDiff('FullYear');
|
|
768
|
-
let months = _getDiff('Month');
|
|
769
|
-
let days = _getDiff('Date');
|
|
770
|
-
let hours = _getDiff('Hours');
|
|
771
|
-
let minutes = _getDiff('Minutes');
|
|
772
|
-
let seconds = _getDiff('Seconds');
|
|
773
|
-
let milliseconds = _getDiff('Milliseconds');
|
|
774
|
-
if (milliseconds < 0) {
|
|
775
|
-
milliseconds += 1000;
|
|
776
|
-
seconds--;
|
|
777
|
-
}
|
|
778
|
-
if (seconds < 0) {
|
|
779
|
-
seconds += 60;
|
|
780
|
-
minutes--;
|
|
781
|
-
}
|
|
782
|
-
if (minutes < 0) {
|
|
783
|
-
minutes += 60;
|
|
784
|
-
hours--;
|
|
785
|
-
}
|
|
786
|
-
if (hours < 0) {
|
|
787
|
-
hours += 24;
|
|
788
|
-
days--;
|
|
789
|
-
}
|
|
790
|
-
if (days < 0) {
|
|
791
|
-
const prevMonth = new Date(to.getFullYear(), to.getMonth(), 0);
|
|
792
|
-
days += prevMonth.getDate();
|
|
793
|
-
months--;
|
|
794
|
-
}
|
|
795
|
-
if (months < 0) {
|
|
796
|
-
months += 12;
|
|
797
|
-
years--;
|
|
798
|
-
}
|
|
799
|
-
const result = {
|
|
800
|
-
years,
|
|
801
|
-
months,
|
|
802
|
-
days,
|
|
803
|
-
hours,
|
|
804
|
-
minutes,
|
|
805
|
-
seconds,
|
|
806
|
-
milliseconds,
|
|
807
|
-
};
|
|
808
|
-
return this.#normalizeDuration(result, absolute, isFuture);
|
|
809
|
-
}
|
|
810
|
-
durationString(options) {
|
|
811
|
-
const { toTime, absolute = true, maxUnits = 7, separator = ', ', style = 'full', showZero = false, } = options ?? {};
|
|
812
|
-
const duration = this.duration(toTime, absolute);
|
|
813
|
-
const units = {
|
|
814
|
-
years: 'y',
|
|
815
|
-
months: 'mo',
|
|
816
|
-
days: 'd',
|
|
817
|
-
hours: 'h',
|
|
818
|
-
minutes: 'm',
|
|
819
|
-
seconds: 's',
|
|
820
|
-
milliseconds: 'ms',
|
|
821
|
-
};
|
|
822
|
-
const _formatUnit = (unit, value) => {
|
|
823
|
-
if (style === 'short') {
|
|
824
|
-
return `${value}${units[unit]}`;
|
|
825
|
-
}
|
|
826
|
-
const $unit = Math.abs(value) === 1 ? unit.slice(0, -1) : unit;
|
|
827
|
-
return `${value} ${$unit}`;
|
|
828
|
-
};
|
|
829
|
-
const parts = Object.entries(duration)
|
|
830
|
-
.filter(([_, value]) => showZero || Math.abs(value) > 0)
|
|
831
|
-
.slice(0, maxUnits)
|
|
832
|
-
.map(([unit, value]) => _formatUnit(unit, value));
|
|
833
|
-
return (parts.length ? parts.join(separator)
|
|
834
|
-
: style === 'short' ? '0s'
|
|
835
|
-
: '0 seconds');
|
|
836
|
-
}
|
|
837
746
|
day(index) {
|
|
838
747
|
return constants_1.DAYS[index ?? this.weekDay];
|
|
839
748
|
}
|
|
@@ -1050,3 +959,5 @@ class Chronos {
|
|
|
1050
959
|
}
|
|
1051
960
|
exports.Chronos = Chronos;
|
|
1052
961
|
_a = Chronos;
|
|
962
|
+
var chronos_fn_1 = require("./chronos-fn");
|
|
963
|
+
Object.defineProperty(exports, "chronos", { enumerable: true, get: function () { return chronos_fn_1.chronos; } });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.INTERNALS = exports.ZODIAC_PRESETS = exports.VEDIC_ZODIAC_SIGNS = exports.WESTERN_ZODIAC_SIGNS = exports.
|
|
3
|
+
exports.INTERNALS = exports.ZODIAC_PRESETS = exports.VEDIC_ZODIAC_SIGNS = exports.WESTERN_ZODIAC_SIGNS = exports.DATE_PART_RANGES = exports.SORTED_TIME_FORMATS = exports.TIME_FORMATS = exports.MILLISECOND_FORMATS = exports.ZONE_FORMATS = exports.SECOND_FORMATS = exports.MINUTE_FORMATS = exports.HOUR_FORMATS = exports.DAY_FORMATS = exports.DATE_FORMATS = exports.MONTH_FORMATS = exports.YEAR_FORMATS = exports.MONTHS = exports.DAYS = void 0;
|
|
4
4
|
exports.DAYS = Object.freeze([
|
|
5
5
|
'Sunday',
|
|
6
6
|
'Monday',
|
|
@@ -51,7 +51,7 @@ exports.SORTED_TIME_FORMATS = Object.freeze([
|
|
|
51
51
|
...exports.TIME_FORMATS,
|
|
52
52
|
...exports.ZONE_FORMATS,
|
|
53
53
|
].sort((a, b) => b.length - a.length));
|
|
54
|
-
exports.
|
|
54
|
+
exports.DATE_PART_RANGES = Object.freeze({
|
|
55
55
|
night: ['21', '23'],
|
|
56
56
|
midnight: ['00', '01'],
|
|
57
57
|
lateNight: ['02', '04'],
|
package/dist/cjs/date/guards.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.isLeapYear = isLeapYear;
|
|
|
7
7
|
exports.isDateLike = isDateLike;
|
|
8
8
|
const primitives_1 = require("../guards/primitives");
|
|
9
9
|
const specials_1 = require("../guards/specials");
|
|
10
|
+
const utilities_1 = require("../number/utilities");
|
|
10
11
|
const timezone_1 = require("./timezone");
|
|
11
12
|
function isValidTime(value) {
|
|
12
13
|
if (!(0, primitives_1.isString)(value))
|
|
@@ -25,7 +26,8 @@ function isValidTimeZoneId(value) {
|
|
|
25
26
|
return (0, primitives_1.isString)(value) ? value in timezone_1.TIME_ZONE_IDS : false;
|
|
26
27
|
}
|
|
27
28
|
function isLeapYear(year) {
|
|
28
|
-
|
|
29
|
+
const $year = (0, utilities_1.normalizeNumber)(year);
|
|
30
|
+
return $year ? ($year % 4 === 0 && $year % 100 !== 0) || $year % 400 === 0 : false;
|
|
29
31
|
}
|
|
30
32
|
function isDateLike(value) {
|
|
31
33
|
if (value instanceof Date)
|
|
@@ -5,7 +5,7 @@ const non_primitives_1 = require("../../guards/non-primitives");
|
|
|
5
5
|
const primitives_1 = require("../../guards/primitives");
|
|
6
6
|
const constants_1 = require("../constants");
|
|
7
7
|
const businessPlugin = (ChronosClass) => {
|
|
8
|
-
const internalDate = ChronosClass[constants_1.INTERNALS]
|
|
8
|
+
const { internalDate } = ChronosClass[constants_1.INTERNALS];
|
|
9
9
|
ChronosClass.prototype.isWeekend = function (determiner = 0, weekendLength = 2) {
|
|
10
10
|
const day = internalDate(this).getDay();
|
|
11
11
|
if ((0, non_primitives_1.isValidArray)(determiner)) {
|
|
@@ -6,7 +6,7 @@ const dayPartPlugin = (ChronosClass) => {
|
|
|
6
6
|
ChronosClass.prototype.getPartOfDay = function (config) {
|
|
7
7
|
const hour = this.hour;
|
|
8
8
|
const ranges = {
|
|
9
|
-
...constants_1.
|
|
9
|
+
...constants_1.DATE_PART_RANGES,
|
|
10
10
|
...config,
|
|
11
11
|
};
|
|
12
12
|
for (const [part, [start, end]] of Object.entries(ranges)) {
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.durationPlugin = void 0;
|
|
4
|
+
const constants_1 = require("../constants");
|
|
5
|
+
const durationPlugin = (ChronosClass) => {
|
|
6
|
+
const { internalDate, toNewDate } = ChronosClass[constants_1.INTERNALS];
|
|
7
|
+
const _normalizeDuration = (result, absolute, isFuture) => {
|
|
8
|
+
const entries = Object.entries(result);
|
|
9
|
+
const updated = { ...result };
|
|
10
|
+
if (!absolute && !isFuture) {
|
|
11
|
+
for (const [key, value] of entries) {
|
|
12
|
+
if (value !== 0) {
|
|
13
|
+
updated[key] = value * -1;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
else if (absolute) {
|
|
18
|
+
for (const [key, value] of entries) {
|
|
19
|
+
updated[key] = Math.abs(value);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return updated;
|
|
23
|
+
};
|
|
24
|
+
ChronosClass.prototype.duration = function (toTime, absolute = true) {
|
|
25
|
+
const now = internalDate(this);
|
|
26
|
+
const target = toNewDate(this, toTime);
|
|
27
|
+
const isFuture = target > now;
|
|
28
|
+
const from = isFuture ? now : target;
|
|
29
|
+
const to = isFuture ? target : now;
|
|
30
|
+
const _getDiff = (suffix) => {
|
|
31
|
+
const method = ('get' + suffix);
|
|
32
|
+
return to[method]() - from[method]();
|
|
33
|
+
};
|
|
34
|
+
let years = _getDiff('FullYear');
|
|
35
|
+
let months = _getDiff('Month');
|
|
36
|
+
let days = _getDiff('Date');
|
|
37
|
+
let hours = _getDiff('Hours');
|
|
38
|
+
let minutes = _getDiff('Minutes');
|
|
39
|
+
let seconds = _getDiff('Seconds');
|
|
40
|
+
let milliseconds = _getDiff('Milliseconds');
|
|
41
|
+
if (milliseconds < 0) {
|
|
42
|
+
milliseconds += 1000;
|
|
43
|
+
seconds--;
|
|
44
|
+
}
|
|
45
|
+
if (seconds < 0) {
|
|
46
|
+
seconds += 60;
|
|
47
|
+
minutes--;
|
|
48
|
+
}
|
|
49
|
+
if (minutes < 0) {
|
|
50
|
+
minutes += 60;
|
|
51
|
+
hours--;
|
|
52
|
+
}
|
|
53
|
+
if (hours < 0) {
|
|
54
|
+
hours += 24;
|
|
55
|
+
days--;
|
|
56
|
+
}
|
|
57
|
+
if (days < 0) {
|
|
58
|
+
const prevMonth = new Date(to.getFullYear(), to.getMonth(), 0);
|
|
59
|
+
days += prevMonth.getDate();
|
|
60
|
+
months--;
|
|
61
|
+
}
|
|
62
|
+
if (months < 0) {
|
|
63
|
+
months += 12;
|
|
64
|
+
years--;
|
|
65
|
+
}
|
|
66
|
+
const result = {
|
|
67
|
+
years,
|
|
68
|
+
months,
|
|
69
|
+
days,
|
|
70
|
+
hours,
|
|
71
|
+
minutes,
|
|
72
|
+
seconds,
|
|
73
|
+
milliseconds,
|
|
74
|
+
};
|
|
75
|
+
return _normalizeDuration(result, absolute, isFuture);
|
|
76
|
+
};
|
|
77
|
+
ChronosClass.prototype.durationString = function (options) {
|
|
78
|
+
const { toTime, absolute = true, maxUnits = 7, separator = ', ', style = 'full', showZero = false, } = options ?? {};
|
|
79
|
+
const duration = this.duration(toTime, absolute);
|
|
80
|
+
const units = {
|
|
81
|
+
years: 'y',
|
|
82
|
+
months: 'mo',
|
|
83
|
+
days: 'd',
|
|
84
|
+
hours: 'h',
|
|
85
|
+
minutes: 'm',
|
|
86
|
+
seconds: 's',
|
|
87
|
+
milliseconds: 'ms',
|
|
88
|
+
};
|
|
89
|
+
const _formatUnit = (unit, value) => {
|
|
90
|
+
if (style === 'short') {
|
|
91
|
+
return `${value}${units[unit]}`;
|
|
92
|
+
}
|
|
93
|
+
const $unit = Math.abs(value) === 1 ? unit.slice(0, -1) : unit;
|
|
94
|
+
return `${value} ${$unit}`;
|
|
95
|
+
};
|
|
96
|
+
const parts = Object.entries(duration)
|
|
97
|
+
.filter(([_, value]) => showZero || Math.abs(value) > 0)
|
|
98
|
+
.slice(0, maxUnits)
|
|
99
|
+
.map(([unit, value]) => _formatUnit(unit, value));
|
|
100
|
+
return (parts.length ? parts.join(separator)
|
|
101
|
+
: style === 'short' ? '0s'
|
|
102
|
+
: '0 seconds');
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
exports.durationPlugin = durationPlugin;
|
|
@@ -4,10 +4,10 @@ exports.fromNowPlugin = void 0;
|
|
|
4
4
|
const convert_1 = require("../../string/convert");
|
|
5
5
|
const constants_1 = require("../constants");
|
|
6
6
|
const fromNowPlugin = (ChronosClass) => {
|
|
7
|
-
const
|
|
7
|
+
const { internalDate, toNewDate } = ChronosClass[constants_1.INTERNALS];
|
|
8
8
|
ChronosClass.prototype.fromNow = function (level = 'second', withSuffixPrefix = true, time) {
|
|
9
|
-
const now =
|
|
10
|
-
const target =
|
|
9
|
+
const now = toNewDate(this, time);
|
|
10
|
+
const target = internalDate(this);
|
|
11
11
|
const isFuture = target > now;
|
|
12
12
|
const from = isFuture ? now : target;
|
|
13
13
|
const to = isFuture ? target : now;
|
|
@@ -3,11 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.relativeTimePlugin = void 0;
|
|
4
4
|
const constants_1 = require("../constants");
|
|
5
5
|
const relativeTimePlugin = (ChronosClass) => {
|
|
6
|
-
const internalDate = ChronosClass[constants_1.INTERNALS]
|
|
7
|
-
const newDate = ChronosClass[constants_1.INTERNALS].toNewDate;
|
|
6
|
+
const { internalDate, toNewDate } = ChronosClass[constants_1.INTERNALS];
|
|
8
7
|
ChronosClass.prototype.getRelativeYear = function (time) {
|
|
9
8
|
const inputDate = internalDate(this);
|
|
10
|
-
const now =
|
|
9
|
+
const now = toNewDate(this, time);
|
|
11
10
|
let years = inputDate.getFullYear() - now.getFullYear();
|
|
12
11
|
const noYearMonthDay = now.getMonth() < inputDate.getMonth() ||
|
|
13
12
|
(now.getMonth() === inputDate.getMonth() && now.getDate() < inputDate.getDate());
|
|
@@ -17,7 +16,7 @@ const relativeTimePlugin = (ChronosClass) => {
|
|
|
17
16
|
return years;
|
|
18
17
|
};
|
|
19
18
|
ChronosClass.prototype.getRelativeMonth = function (time) {
|
|
20
|
-
const now =
|
|
19
|
+
const now = toNewDate(this, time);
|
|
21
20
|
const inputDate = internalDate(this);
|
|
22
21
|
let months = (inputDate.getFullYear() - now.getFullYear()) * 12 +
|
|
23
22
|
(inputDate.getMonth() - now.getMonth());
|
|
@@ -32,7 +31,7 @@ const relativeTimePlugin = (ChronosClass) => {
|
|
|
32
31
|
return Math.floor(relativeDays / 7);
|
|
33
32
|
};
|
|
34
33
|
ChronosClass.prototype.getRelativeDay = function (time) {
|
|
35
|
-
const today =
|
|
34
|
+
const today = toNewDate(this, time);
|
|
36
35
|
today.setHours(0, 0, 0, 0);
|
|
37
36
|
const inputDate = internalDate(this);
|
|
38
37
|
inputDate.setHours(0, 0, 0, 0);
|
|
@@ -41,19 +40,19 @@ const relativeTimePlugin = (ChronosClass) => {
|
|
|
41
40
|
return diffDays;
|
|
42
41
|
};
|
|
43
42
|
ChronosClass.prototype.getRelativeHour = function (time) {
|
|
44
|
-
const diff = internalDate(this).getTime() -
|
|
43
|
+
const diff = internalDate(this).getTime() - toNewDate(this, time).getTime();
|
|
45
44
|
return Math.floor(diff / (1000 * 60 * 60));
|
|
46
45
|
};
|
|
47
46
|
ChronosClass.prototype.getRelativeMinute = function (time) {
|
|
48
|
-
const diff = internalDate(this).getTime() -
|
|
47
|
+
const diff = internalDate(this).getTime() - toNewDate(this, time).getTime();
|
|
49
48
|
return Math.floor(diff / (1000 * 60));
|
|
50
49
|
};
|
|
51
50
|
ChronosClass.prototype.getRelativeSecond = function (time) {
|
|
52
|
-
const diff = internalDate(this).getTime() -
|
|
51
|
+
const diff = internalDate(this).getTime() - toNewDate(this, time).getTime();
|
|
53
52
|
return Math.floor(diff / 1000);
|
|
54
53
|
};
|
|
55
54
|
ChronosClass.prototype.getRelativeMilliSecond = function (time) {
|
|
56
|
-
return internalDate(this).getTime() -
|
|
55
|
+
return internalDate(this).getTime() - toNewDate(this, time).getTime();
|
|
57
56
|
};
|
|
58
57
|
ChronosClass.prototype.compare = function (unit = 'minute', time) {
|
|
59
58
|
switch (unit) {
|
|
@@ -4,9 +4,9 @@ exports.roundPlugin = void 0;
|
|
|
4
4
|
const utilities_1 = require("../../number/utilities");
|
|
5
5
|
const constants_1 = require("../constants");
|
|
6
6
|
const roundPlugin = (ChronosClass) => {
|
|
7
|
-
const
|
|
7
|
+
const { internalDate, withOrigin } = ChronosClass[constants_1.INTERNALS];
|
|
8
8
|
ChronosClass.prototype.round = function (unit, nearest = 1) {
|
|
9
|
-
const date =
|
|
9
|
+
const date = internalDate(this);
|
|
10
10
|
switch (unit) {
|
|
11
11
|
case 'millisecond': {
|
|
12
12
|
const rounded = (0, utilities_1.roundToNearest)(date.getMilliseconds(), nearest);
|
|
@@ -56,7 +56,7 @@ const roundPlugin = (ChronosClass) => {
|
|
|
56
56
|
const diffToStart = Math.abs(date.getTime() - startOfWeek.getTime());
|
|
57
57
|
const diffToEnd = Math.abs(endOfWeek.getTime() - date.getTime());
|
|
58
58
|
const rounded = diffToEnd < diffToStart ? endOfWeek : startOfWeek;
|
|
59
|
-
return
|
|
59
|
+
return withOrigin(new ChronosClass(rounded), 'round');
|
|
60
60
|
}
|
|
61
61
|
case 'month': {
|
|
62
62
|
const fullMonth = date.getMonth() + date.getDate() / this.lastDateOfMonth;
|
|
@@ -78,7 +78,7 @@ const roundPlugin = (ChronosClass) => {
|
|
|
78
78
|
default:
|
|
79
79
|
return this;
|
|
80
80
|
}
|
|
81
|
-
return
|
|
81
|
+
return withOrigin(new ChronosClass(date), 'round');
|
|
82
82
|
};
|
|
83
83
|
};
|
|
84
84
|
exports.roundPlugin = roundPlugin;
|
|
@@ -6,68 +6,95 @@ const guards_1 = require("../guards");
|
|
|
6
6
|
const timezone_1 = require("../timezone");
|
|
7
7
|
const utils_1 = require("../utils");
|
|
8
8
|
const timeZonePlugin = (ChronosClass) => {
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
if (
|
|
9
|
+
const { internalDate: $Date, withOrigin } = ChronosClass[constants_1.INTERNALS];
|
|
10
|
+
const _isLabelKey = (offset) => {
|
|
11
|
+
return offset in timezone_1.TIME_ZONE_LABELS;
|
|
12
|
+
};
|
|
13
|
+
const _resolveTzName = (offset) => {
|
|
14
|
+
if (_isLabelKey(offset)) {
|
|
15
|
+
return timezone_1.TIME_ZONE_LABELS[offset];
|
|
16
|
+
}
|
|
17
|
+
return undefined;
|
|
18
|
+
};
|
|
19
|
+
const _getTimeZoneName = (zone) => {
|
|
20
|
+
if ((0, guards_1.isValidUTCOffSet)(zone)) {
|
|
21
|
+
return _resolveTzName(zone);
|
|
22
|
+
}
|
|
23
|
+
else if ((0, guards_1.isValidTimeZoneId)(zone)) {
|
|
24
|
+
const record = timezone_1.TIME_ZONE_IDS[zone];
|
|
25
|
+
return record?.tzName ?? _resolveTzName(record?.offset);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
return zone in timezone_1.TIME_ZONES ?
|
|
29
|
+
timezone_1.TIME_ZONES[zone].tzName
|
|
30
|
+
: _resolveTzName(timezone_1.TIME_ZONES[zone].offset);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const TZ_ID_CACHE = new Map(Object.entries(timezone_1.TIME_ZONE_IDS).reduce((acc, [id, { offset }]) => {
|
|
34
|
+
const arr = acc.get(offset) ?? [];
|
|
35
|
+
arr.push(id);
|
|
36
|
+
acc.set(offset, arr);
|
|
37
|
+
return acc;
|
|
38
|
+
}, new Map()));
|
|
39
|
+
const _getTimeZoneId = (utc) => {
|
|
40
|
+
const tzIds = TZ_ID_CACHE.get(utc);
|
|
41
|
+
if (!tzIds || tzIds?.length === 0)
|
|
15
42
|
return undefined;
|
|
16
|
-
if (tzIds
|
|
43
|
+
if (tzIds?.length === 1)
|
|
17
44
|
return tzIds[0];
|
|
18
45
|
return tzIds;
|
|
19
46
|
};
|
|
20
47
|
ChronosClass.prototype.timeZone = function (zone) {
|
|
21
|
-
let
|
|
22
|
-
let stringOffset;
|
|
48
|
+
let offset;
|
|
23
49
|
let tzId;
|
|
24
50
|
if ((0, guards_1.isValidUTCOffSet)(zone)) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
tzId = getTimeZoneId(stringOffset) || stringOffset;
|
|
51
|
+
offset = zone;
|
|
52
|
+
tzId = _getTimeZoneId(offset) || offset;
|
|
28
53
|
}
|
|
29
54
|
else if ((0, guards_1.isValidTimeZoneId)(zone)) {
|
|
30
|
-
|
|
31
|
-
targetOffset = (0, utils_1.extractMinutesFromUTC)(stringOffset);
|
|
55
|
+
offset = timezone_1.TIME_ZONE_IDS[zone].offset;
|
|
32
56
|
tzId = zone;
|
|
33
57
|
}
|
|
34
58
|
else {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
tzId = getTimeZoneId(stringOffset) || stringOffset;
|
|
59
|
+
offset = zone in timezone_1.TIME_ZONES ? timezone_1.TIME_ZONES[zone].offset : timezone_1.TIME_ZONES['UTC'].offset;
|
|
60
|
+
tzId = _getTimeZoneId(offset) || offset;
|
|
38
61
|
}
|
|
62
|
+
const tzName = _getTimeZoneName(zone) ?? timezone_1.TIME_ZONES['UTC'].offset;
|
|
63
|
+
const targetOffset = (0, utils_1.extractMinutesFromUTC)(offset);
|
|
39
64
|
const previousOffset = this.getTimeZoneOffsetMinutes();
|
|
40
65
|
const relativeOffset = targetOffset - previousOffset;
|
|
41
66
|
const adjustedTime = new Date($Date(this).getTime() + relativeOffset * 60 * 1000);
|
|
42
67
|
const instance = new ChronosClass(adjustedTime);
|
|
43
|
-
return
|
|
68
|
+
return withOrigin(instance, `timeZone`, offset, tzName, tzId, zone);
|
|
44
69
|
};
|
|
45
70
|
ChronosClass.prototype.getTimeZoneName = function (utc) {
|
|
46
|
-
const UTC = utc ??
|
|
47
|
-
return
|
|
71
|
+
const UTC = utc ?? this.utcOffset;
|
|
72
|
+
return _getTimeZoneName(this?.$tzTracker ?? UTC) ?? UTC;
|
|
48
73
|
};
|
|
74
|
+
const TZ_SHORT_CACHE = new Map();
|
|
49
75
|
ChronosClass.prototype.getTimeZoneNameShort = function (utc) {
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
76
|
+
const tracker = this?.$tzTracker;
|
|
77
|
+
if (!utc && tracker && tracker in timezone_1.TIME_ZONES)
|
|
78
|
+
return tracker;
|
|
79
|
+
const zone = this.getTimeZoneName(utc);
|
|
80
|
+
if (TZ_SHORT_CACHE.has(zone))
|
|
81
|
+
return TZ_SHORT_CACHE.get(zone);
|
|
82
|
+
const customAbbr = (0, guards_1.isValidUTCOffSet)(zone) || (0, guards_1.isValidTimeZoneId)(zone) ?
|
|
83
|
+
zone
|
|
84
|
+
: zone
|
|
85
|
+
.split(/\s+/)
|
|
86
|
+
.map((w) => w?.[0])
|
|
87
|
+
.join('')
|
|
88
|
+
.replace(/\W/g, '');
|
|
89
|
+
TZ_SHORT_CACHE.set(zone, customAbbr);
|
|
90
|
+
return customAbbr;
|
|
64
91
|
};
|
|
65
92
|
ChronosClass.prototype.toString = function () {
|
|
66
|
-
const offset =
|
|
93
|
+
const offset = this.utcOffset;
|
|
67
94
|
switch (this.origin) {
|
|
68
95
|
case 'timeZone': {
|
|
69
96
|
const gmt = offset.replace('UTC', 'GMT').replace(':', '');
|
|
70
|
-
const label =
|
|
97
|
+
const label = this.getTimeZoneName();
|
|
71
98
|
return $Date(this)
|
|
72
99
|
.toString()
|
|
73
100
|
.replace(/GMT[+-]\d{4}\s+\([^)]+\)/, `${gmt} (${label})`);
|