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.
Files changed (34) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +2 -2
  3. package/dist/cjs/date/Chronos.js +21 -110
  4. package/dist/cjs/date/constants.js +2 -2
  5. package/dist/cjs/date/guards.js +3 -1
  6. package/dist/cjs/date/plugins/businessPlugin.js +1 -1
  7. package/dist/cjs/date/plugins/dayPartPlugin.js +1 -1
  8. package/dist/cjs/date/plugins/durationPlugin.js +105 -0
  9. package/dist/cjs/date/plugins/fromNowPlugin.js +3 -3
  10. package/dist/cjs/date/plugins/relativeTimePlugin.js +8 -9
  11. package/dist/cjs/date/plugins/roundPlugin.js +4 -4
  12. package/dist/cjs/date/plugins/timeZonePlugin.js +63 -36
  13. package/dist/cjs/date/timezone.js +3242 -743
  14. package/dist/dts/date/Chronos.d.ts +22 -37
  15. package/dist/dts/date/constants.d.ts +1 -1
  16. package/dist/dts/date/guards.d.ts +3 -3
  17. package/dist/dts/date/plugins/durationPlugin.d.ts +22 -0
  18. package/dist/dts/date/plugins/relativeTimePlugin.d.ts +15 -11
  19. package/dist/dts/date/plugins/timeZonePlugin.d.ts +33 -8
  20. package/dist/dts/date/timezone.d.ts +3288 -878
  21. package/dist/dts/date/types.d.ts +23 -17
  22. package/dist/dts/date/utils.d.ts +4 -4
  23. package/dist/esm/date/Chronos.js +19 -109
  24. package/dist/esm/date/constants.js +1 -1
  25. package/dist/esm/date/guards.js +3 -1
  26. package/dist/esm/date/plugins/businessPlugin.js +1 -1
  27. package/dist/esm/date/plugins/dayPartPlugin.js +2 -2
  28. package/dist/esm/date/plugins/durationPlugin.js +101 -0
  29. package/dist/esm/date/plugins/fromNowPlugin.js +3 -3
  30. package/dist/esm/date/plugins/relativeTimePlugin.js +8 -9
  31. package/dist/esm/date/plugins/roundPlugin.js +4 -4
  32. package/dist/esm/date/plugins/timeZonePlugin.js +64 -37
  33. package/dist/esm/date/timezone.js +3242 -743
  34. 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
@@ -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.toISOString().replace(/\.\d+(Z|[+-]\d{2}:\d{2})?$/, ''), replacement);
84
+ return string.replace(this.#isoTzRemoved(), replacement);
84
85
  default:
85
- return string.replace(this.toLocalISOString().replace(/\.\d+(Z|[+-]\d{2}:\d{2})?$/, ''), replacement);
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.toISOString().replace(/\.\d+(Z|[+-]\d{2}:\d{2})?$/, ''));
94
+ return string.indexOf(this.#isoTzRemoved());
94
95
  default:
95
- return string.indexOf(this.toLocalISOString().replace(/\.\d+(Z|[+-]\d{2}:\d{2})?$/, ''));
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.toISOString().replace(/\.\d+(Z|[+-]\d{2}:\d{2})?$/, ''));
104
+ return string.split(this.#isoTzRemoved());
104
105
  default:
105
- return string.split(this.toLocalISOString().replace(/\.\d+(Z|[+-]\d{2}:\d{2})?$/, ''));
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
- #normalizeDuration(result, absolute, isFuture) {
232
- const entries = Object.entries(result);
233
- const updated = { ...result };
234
- if (!absolute && !isFuture) {
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.DEFAULT_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;
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.DEFAULT_RANGES = Object.freeze({
54
+ exports.DATE_PART_RANGES = Object.freeze({
55
55
  night: ['21', '23'],
56
56
  midnight: ['00', '01'],
57
57
  lateNight: ['02', '04'],
@@ -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
- return (Number(year) % 4 === 0 && Number(year) % 100 !== 0) || Number(year) % 400 === 0;
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].internalDate;
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.DEFAULT_RANGES,
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 internal = ChronosClass[constants_1.INTERNALS];
7
+ const { internalDate, toNewDate } = ChronosClass[constants_1.INTERNALS];
8
8
  ChronosClass.prototype.fromNow = function (level = 'second', withSuffixPrefix = true, time) {
9
- const now = internal.toNewDate(this, time);
10
- const target = internal.internalDate(this);
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].internalDate;
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 = newDate(this, time);
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 = newDate(this, time);
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 = newDate(this, time);
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() - newDate(this, time).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() - newDate(this, time).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() - newDate(this, time).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() - newDate(this, time).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 internal = ChronosClass[constants_1.INTERNALS];
7
+ const { internalDate, withOrigin } = ChronosClass[constants_1.INTERNALS];
8
8
  ChronosClass.prototype.round = function (unit, nearest = 1) {
9
- const date = internal.internalDate(this);
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 internal.withOrigin(new ChronosClass(rounded), 'round');
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 internal.withOrigin(new ChronosClass(date), 'round');
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 internal = ChronosClass[constants_1.INTERNALS];
10
- const $Date = internal.internalDate;
11
- const getTimeZoneId = (utc) => {
12
- const obj = { ...timezone_1.TIME_ZONE_IDS };
13
- const tzIds = Object.keys(obj).filter((key) => obj[key] === utc);
14
- if (!tzIds || tzIds.length === 0)
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.length === 1)
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 targetOffset;
22
- let stringOffset;
48
+ let offset;
23
49
  let tzId;
24
50
  if ((0, guards_1.isValidUTCOffSet)(zone)) {
25
- targetOffset = (0, utils_1.extractMinutesFromUTC)(zone);
26
- stringOffset = zone;
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
- stringOffset = timezone_1.TIME_ZONE_IDS[zone];
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
- targetOffset = timezone_1.TIME_ZONES?.[zone] ?? timezone_1.TIME_ZONES['UTC'];
36
- stringOffset = (0, utils_1.formatUTCOffset)(targetOffset);
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 internal.withOrigin(instance, 'timeZone', stringOffset, this.getTimeZoneName(stringOffset), tzId);
68
+ return withOrigin(instance, `timeZone`, offset, tzName, tzId, zone);
44
69
  };
45
70
  ChronosClass.prototype.getTimeZoneName = function (utc) {
46
- const UTC = utc ?? `UTC${this.getTimeZoneOffset()}`;
47
- return timezone_1.TIME_ZONE_LABELS?.[UTC] ?? UTC;
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 mins = utc ? (0, utils_1.extractMinutesFromUTC)(utc) : this.getTimeZoneOffsetMinutes();
51
- const UTC = (0, utils_1.formatUTCOffset)(mins);
52
- const timeZone = timezone_1.TIME_ZONE_LABELS?.[UTC];
53
- let result = timeZone
54
- ?.split(/\s+/)
55
- ?.filter(Boolean)
56
- ?.map((part) => part?.[0])
57
- ?.join('')
58
- ?.replace(/\W/g, '');
59
- if (!result) {
60
- const zones = Object.entries(timezone_1.TIME_ZONES);
61
- result = zones.find((zone) => zone?.[1] === mins)?.[0];
62
- }
63
- return result ?? (0, utils_1.formatUTCOffset)(mins);
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 = internal.offset(this);
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 = timezone_1.TIME_ZONE_LABELS[offset] ?? offset;
97
+ const label = this.getTimeZoneName();
71
98
  return $Date(this)
72
99
  .toString()
73
100
  .replace(/GMT[+-]\d{4}\s+\([^)]+\)/, `${gmt} (${label})`);