nhb-toolbox 4.28.71 → 4.28.80

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 CHANGED
@@ -4,6 +4,17 @@
4
4
 
5
5
  All notable changes to the package will be documented here.
6
6
 
7
+ ## [4.28.80] - 2026-02-07
8
+
9
+ - **Moved** `getDatesInRange` method to `Chronos` *plugin system*, usable via `dateRangePlugin`.
10
+ - **Updated** `Timestamp` type to `ISOTimeString` and removed *branding* for better clarity and consistency across the codebase.
11
+ - `Chronos` methods `toISOString()` and `toLocalISOString()`; and `getTimestamp` utility now return `ISOTimeString` type.
12
+ - `Chronos` method `getDatesInRange(...)` now return `ISOTimeString[]` instead of `string[]`.
13
+
14
+ ## [4.28.72] - 2026-02-06
15
+
16
+ - **Updated** *tsdoc* for the overload signatures of `getTimestamp` utility to clarify the behavior.
17
+
7
18
  ## [4.28.71] - 2026-02-06
8
19
 
9
20
  - **Fixed** an *issue* in `reconstruct` method of `Chronos` class where the *internal state* of the reconstructed instance was not properly when the timezone offset is different from the local system's timezone offset.
package/README.md CHANGED
@@ -515,31 +515,31 @@ debounceAction(fetchResults, 300);
515
515
 
516
516
  ## 🔗 Related Packages
517
517
 
518
- <div title="React Hooks: nhb-hooks" style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
518
+ <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
519
519
  <a target="_blank" href="https://www.npmjs.com/package/nhb-hooks">
520
520
  <img src="https://img.shields.io/badge/React_Hooks-nhb--hooks-blue" alt="nhb-hooks" />
521
521
  </a>
522
522
  </div>
523
523
 
524
- <div title="IndexedDB ORM: locality-idb" style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
524
+ <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
525
525
  <a target="_blank" href="https://www.npmjs.com/package/locality-idb">
526
526
  <img src="https://img.shields.io/badge/IndexedDB_ORM-locality--idb-darkviolet" alt="locality-idb" />
527
527
  </a>
528
528
  </div>
529
529
 
530
- <div title="Development Scripts: nhb-scripts" style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
530
+ <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
531
531
  <a target="_blank" href="https://www.npmjs.com/package/nhb-scripts">
532
532
  <img src="https://img.shields.io/badge/Development_Scripts-nhb--scripts-red" alt="nhb-scripts" />
533
533
  </a>
534
534
  </div>
535
535
 
536
- <div title="Express Server Scaffolder: nhb-express" style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
536
+ <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
537
537
  <a target="_blank" href="https://www.npmjs.com/package/nhb-express">
538
538
  <img src="https://img.shields.io/badge/Express_Server_Scaffolder-nhb--express-orange" alt="nhb-express" />
539
539
  </a>
540
540
  </div>
541
541
 
542
- <div title="Anagram Generator: nhb-anagram-generator" style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
542
+ <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
543
543
  <a target="_blank" href="https://www.npmjs.com/package/nhb-anagram-generator">
544
544
  <img src="https://img.shields.io/badge/Anagram_Generator-nhb--anagram--generator-teal" alt="nhb-anagram-generator" />
545
545
  </a>
@@ -2,7 +2,6 @@
2
2
  var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.INTERNALS = exports.Chronus = exports.chronusts = exports.chronusjs = exports.chronus = exports.chronosts = exports.chronosjs = exports.chronos = exports.Chronos = void 0;
5
- const non_primitives_1 = require("../guards/non-primitives");
6
5
  const primitives_1 = require("../guards/primitives");
7
6
  const constants_1 = require("./constants");
8
7
  const guards_1 = require("./guards");
@@ -592,44 +591,6 @@ class Chronos {
592
591
  monthName(index) {
593
592
  return constants_1.MONTHS[index ?? this.month];
594
593
  }
595
- getDatesInRange(options) {
596
- let startDate = this.clone(), endDate = this.addWeeks(4);
597
- const { format = 'local', onlyDays, skipDays, roundDate = false } = options ?? {};
598
- if (options) {
599
- if ('from' in options || 'to' in options) {
600
- if (options?.from)
601
- startDate = _a.#cast(options.from);
602
- if (options?.to)
603
- endDate = _a.#cast(options.to);
604
- }
605
- else if ('span' in options || 'unit' in options) {
606
- const { span = 4, unit = 'week' } = options;
607
- endDate = startDate.add(span, unit);
608
- }
609
- }
610
- if (roundDate) {
611
- startDate = startDate.startOf('day');
612
- endDate = endDate.startOf('day');
613
- }
614
- const skipSet = new Set(((0, non_primitives_1.isValidArray)(onlyDays) ? onlyDays
615
- : (0, non_primitives_1.isValidArray)(skipDays) ? skipDays
616
- : []).map((day) => ((0, primitives_1.isNumber)(day) ? day : constants_1.DAYS.indexOf(day))));
617
- const dates = [];
618
- const startTime = startDate.#timestamp;
619
- const endTime = endDate.#timestamp;
620
- const step = (startTime <= endTime ? 1 : -1) * constants_1.MS_PER_DAY;
621
- const totalDays = Math.floor(Math.abs(endTime - startTime) / constants_1.MS_PER_DAY);
622
- for (let i = 0; i <= totalDays; i++) {
623
- const ts = startTime + i * step;
624
- const wDay = new Date(ts).getDay();
625
- const include = (0, non_primitives_1.isValidArray)(onlyDays) ? skipSet.has(wDay) : !skipSet.has(wDay);
626
- if (include) {
627
- const chr = new _a(ts).#withOrigin('clone', startDate.#offset, startDate.timeZoneName, startDate.timeZoneId, startDate.$tzTracker);
628
- dates.push(format === 'local' ? chr.toLocalISOString() : chr.toISOString());
629
- }
630
- }
631
- return dates;
632
- }
633
594
  static parse(dateStr, format) {
634
595
  const tokenPatterns = {
635
596
  YYYY: '(?<YYYY>\\d{4})',
@@ -814,9 +775,9 @@ class Chronos {
814
775
  }
815
776
  const { native, origin, utcOffset, timeZoneName, timeZoneId, $tzTracker } = value;
816
777
  const offsetMins = (0, utils_1.extractMinutesFromUTC)(utcOffset);
817
- const instance = new _a(native);
818
- const diffMins = instance.getTimeZoneOffsetMinutes() - offsetMins;
819
- const target = instance.utcOffset === utcOffset ? instance : instance.add(-diffMins, 'minute');
778
+ const chr = new _a(native);
779
+ const diffMins = chr.getTimeZoneOffsetMinutes() - offsetMins;
780
+ const target = chr.utcOffset === utcOffset ? chr : chr.add(-diffMins, 'minute');
820
781
  return target.#withOrigin(origin, utcOffset, timeZoneName, timeZoneId, $tzTracker);
821
782
  }
822
783
  static use(plugin) {
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dateRangePlugin = void 0;
4
+ const non_primitives_1 = require("../../guards/non-primitives");
5
+ const primitives_1 = require("../../guards/primitives");
6
+ const Chronos_1 = require("../Chronos");
7
+ const constants_1 = require("../constants");
8
+ const dateRangePlugin = ($Chronos) => {
9
+ const { internalDate: $Date, cast, withOrigin, offset } = $Chronos[Chronos_1.INTERNALS];
10
+ $Chronos.prototype.getDatesInRange = function (options) {
11
+ let startDate = this.clone(), endDate = this.addWeeks(4);
12
+ const { format = 'local', onlyDays, skipDays, roundDate = false } = options ?? {};
13
+ if (options) {
14
+ if ('from' in options || 'to' in options) {
15
+ if (options?.from)
16
+ startDate = cast(options.from);
17
+ if (options?.to)
18
+ endDate = cast(options.to);
19
+ }
20
+ else if ('span' in options || 'unit' in options) {
21
+ const { span = 4, unit = 'week' } = options;
22
+ endDate = startDate.add(span, unit);
23
+ }
24
+ }
25
+ if (roundDate) {
26
+ startDate = startDate.startOf('day');
27
+ endDate = endDate.startOf('day');
28
+ }
29
+ const skippedDays = (0, non_primitives_1.isValidArray)(onlyDays) ? onlyDays
30
+ : (0, non_primitives_1.isValidArray)(skipDays) ? skipDays
31
+ : [];
32
+ const skipSet = new Set(skippedDays.map((day) => ((0, primitives_1.isNumber)(day) ? day : constants_1.DAYS.indexOf(day))));
33
+ const dates = [];
34
+ const startTime = $Date(startDate).getTime();
35
+ const endTime = $Date(endDate).getTime();
36
+ const step = (startTime <= endTime ? 1 : -1) * constants_1.MS_PER_DAY;
37
+ const totalDays = Math.floor(Math.abs(endTime - startTime) / constants_1.MS_PER_DAY);
38
+ for (let i = 0; i <= totalDays; i++) {
39
+ const ts = startTime + i * step;
40
+ const wDay = new Date(ts).getDay();
41
+ const include = (0, non_primitives_1.isValidArray)(onlyDays) ? skipSet.has(wDay) : !skipSet.has(wDay);
42
+ if (include) {
43
+ const chr = withOrigin(new $Chronos(ts), 'clone', offset(this), startDate.timeZoneName, startDate.timeZoneId, startDate.$tzTracker);
44
+ dates.push(format === 'local' ? chr.toLocalISOString() : chr.toISOString());
45
+ }
46
+ }
47
+ return dates;
48
+ };
49
+ };
50
+ exports.dateRangePlugin = dateRangePlugin;
@@ -1,7 +1,7 @@
1
1
  import type { Enumerate, NumberRange } from '../number/types';
2
2
  import type { LooseLiteral, TupleOf } from '../utils/types';
3
3
  import { INTERNALS } from './constants';
4
- import type { $NativeTzNameOrId, $TimeZoneIdentifier, $UTCOffset, ChronosInput, ChronosInternals, ChronosMethods, ChronosObject, ChronosPlugin, ChronosProperties, ChronosWithOptions, DateRangeOptions, DateTimeFormatOptions, FormatOptions, LocalesArguments, Milliseconds, MonthName, Quarter, RangeWithDates, RelativeDateRange, RelativeRangeOptions, StrictFormat, TimeOnlyFormat, TimeUnit, TimeUnitValue, TimeZone, TimeZoneId, TimeZoneIdNative, TimeZoneName, UTCOffset, WeekDay } from './types';
4
+ import type { $NativeTzNameOrId, $TimeZoneIdentifier, $UTCOffset, ChronosInput, ChronosInternals, ChronosMethods, ChronosObject, ChronosPlugin, ChronosProperties, ChronosWithOptions, DateRangeOptions, DateTimeFormatOptions, FormatOptions, ISOTimeString, LocalesArguments, Milliseconds, MonthName, Quarter, RelativeRangeOptions, StrictFormat, TimeOnlyFormat, TimeUnit, TimeUnitValue, TimeZone, TimeZoneId, TimeZoneIdNative, TimeZoneName, UTCOffset, WeekDay } from './types';
5
5
  /**
6
6
  * @class Creates a new immutable `Chronos` instance.
7
7
  * - **Note**: *If a date is provided **without a time component**, the instance will default to `00:00:00.000` UTC
@@ -208,9 +208,9 @@ export declare class Chronos {
208
208
  /** @instance Returns a string representation of a date. */
209
209
  toString(): string;
210
210
  /** @instance Returns ISO time string in appropriate time zone with offset. */
211
- toLocalISOString(): string;
211
+ toLocalISOString(): ISOTimeString;
212
212
  /** @instance Returns a date as a string value in ISO format (UTC). */
213
- toISOString(): string;
213
+ toISOString(): ISOTimeString;
214
214
  /**
215
215
  * @instance Wrapper over native {@link Date.toLocaleString} with improved type system.
216
216
  * @description Converts a date and time to a string by using the current or specified locale.
@@ -548,66 +548,6 @@ export declare class Chronos {
548
548
  * @returns Name of the month, e.g., `'January'`, `'February'` etc.
549
549
  */
550
550
  monthName(index?: Enumerate<12>): MonthName;
551
- /**
552
- * @instance Returns an array of ISO date strings within a specific date range.
553
- *
554
- * - If the input is a fixed range (`from` and `to`), it includes all dates between them.
555
- * - If the input is a relative range (`span` and `unit`), it starts from current date and goes forward.
556
- * - If `skipDays` are provided, matching weekdays are excluded from the result.
557
- *
558
- * @param options - Configuration for the date range. Accepts a fixed (`RangeWithDates`) format.
559
- * @returns Array of ISO date strings in either local or UTC format, excluding any skipped weekdays if specified.
560
- *
561
- * - Please refer to {@link https://toolbox.nazmul-nhb.dev/docs/classes/Chronos/calculation#getdatesinrange docs} for details.
562
- *
563
- * @remarks
564
- * - When using `Chronos` instances for `from` and/or `to`, ensure both are created in the **same time zone** to avoid mismatched boundaries.
565
- * - Mixing zones may shift the interpreted start or end by several hours, which can cause the range to include or exclude incorrect weekdays.
566
- *
567
- * @example
568
- * // Using a fixed date range:
569
- * new Chronos().getDatesInRange({ from: '2025-01-01', to: '2025-01-03' });
570
- * // → ['2025-01-01T00:00:00+06:00', '2025-01-02T00:00:00+06:00', '2025-01-03T00:00:00+06:00']
571
- *
572
- * @example
573
- * // Using a relative date range with skipDays:
574
- * new Chronos().getDatesInRange({ span: 7, unit: 'day', skipDays: ['Saturday', 'Sunday'] });
575
- * // → Array of 7 dates excluding weekends
576
- *
577
- * @example
578
- * // UTC format:
579
- * new Chronos().getDatesInRange({ span: 2, unit: 'day', format: 'utc' });
580
- * // → ['2025-06-16T00:00:00.000Z', '2025-06-17T00:00:00.000Z']
581
- */
582
- getDatesInRange(options?: RangeWithDates): string[];
583
- /**
584
- * @instance Returns an array of ISO date strings within a specific date range.
585
- *
586
- * - If the input is a fixed range (`from` and `to`), it includes all dates between them.
587
- * - If the input is a relative range (`span` and `unit`), it starts from current date and goes forward.
588
- * - If `skipDays` are provided, matching weekdays are excluded from the result.
589
- *
590
- * @param options - Configuration for the date range. Accepts a relative (`RelativeDateRange`) format.
591
- * @returns Array of ISO date strings in either local or UTC format, excluding any skipped weekdays if specified.
592
- *
593
- * - Please refer to {@link https://toolbox.nazmul-nhb.dev/docs/classes/Chronos/calculation#getdatesinrange docs} for details.
594
- *
595
- * @example
596
- * // Using a relative date range with skipDays:
597
- * new Chronos().getDatesInRange({ span: 7, unit: 'day', skipDays: ['Saturday', 'Sunday'] });
598
- * // → Array of 7 dates excluding weekends
599
- *
600
- * @example
601
- * // UTC format:
602
- * new Chronos().getDatesInRange({ span: 2, unit: 'day', format: 'utc' });
603
- * // → ['2025-06-16T00:00:00.000Z', '2025-06-17T00:00:00.000Z']
604
- *
605
- * @example
606
- * // Using a fixed date range:
607
- * new Chronos().getDatesInRange({ from: '2025-01-01', to: '2025-01-03' });
608
- * // → ['2025-01-01T00:00:00+06:00', '2025-01-02T00:00:00+06:00', '2025-01-03T00:00:00+06:00']
609
- */
610
- getDatesInRange(options?: RelativeDateRange): string[];
611
551
  /**
612
552
  * @static Parses a date string with a given format (limited support only).
613
553
  *
@@ -17,7 +17,7 @@ export declare const SECOND_FORMATS: readonly ["ss", "s"];
17
17
  export declare const MILLISECOND_FORMATS: readonly ["ms", "mss"];
18
18
  export declare const TIME_FORMATS: readonly ["a", "A"];
19
19
  export declare const EXTRA_FORMATS: readonly ["Z", "ZZ", "S", "SS"];
20
- export declare const SORTED_TIME_FORMATS: readonly ("MM" | "SS" | "ms" | "DD" | "D" | "Do" | "M" | "mmm" | "mmmm" | "d" | "dd" | "ddd" | "YYYY" | "YY" | "yyyy" | "yy" | "H" | "HH" | "hh" | "h" | "mm" | "m" | "a" | "A" | "ss" | "s" | "mss" | "S" | "Z" | "ZZ")[];
20
+ export declare const SORTED_TIME_FORMATS: readonly ("MM" | "SS" | "ms" | "Z" | "DD" | "D" | "Do" | "M" | "mmm" | "mmmm" | "d" | "dd" | "ddd" | "YYYY" | "YY" | "yyyy" | "yy" | "H" | "HH" | "hh" | "h" | "mm" | "m" | "a" | "A" | "ss" | "s" | "mss" | "S" | "ZZ")[];
21
21
  /** Ranges for day parts. */
22
22
  export declare const DATE_PART_RANGES: Readonly<Record<DayPart, [ClockHour, ClockHour]>>;
23
23
  /** Western Zodiac Signs */
@@ -0,0 +1,67 @@
1
+ import type { $Chronos, ISOTimeString, RangeWithDates, RelativeDateRange } from '../types';
2
+ declare module '../Chronos' {
3
+ interface Chronos {
4
+ /**
5
+ * @instance Returns an array of ISO date-time strings within a specific date range.
6
+ *
7
+ * - If the input is a fixed range (`from` and `to`), it includes all dates between them.
8
+ * - If the input is a relative range (`span` and `unit`), it starts from current date and goes forward.
9
+ * - If `skipDays` are provided, matching weekdays are excluded from the result.
10
+ *
11
+ * @param options - Configuration for the date range. Accepts a fixed (`RangeWithDates`) format.
12
+ * @returns Array of ISO date-time strings in either local or UTC format, excluding any skipped weekdays if specified.
13
+ *
14
+ * - Please refer to {@link https://toolbox.nazmul-nhb.dev/docs/classes/Chronos/calculation#getdatesinrange docs} for details.
15
+ *
16
+ * @remarks
17
+ * - When using `Chronos` instances for `from` and/or `to`, ensure both are created in the **same time zone** to avoid mismatched boundaries.
18
+ * - Mixing zones may shift the interpreted start or end by several hours, which can cause the range to include or exclude incorrect weekdays.
19
+ *
20
+ * @example
21
+ * // Using a fixed date range:
22
+ * new Chronos().getDatesInRange({ from: '2025-01-01', to: '2025-01-03' });
23
+ * // → ['2025-01-01T00:00:00+06:00', '2025-01-02T00:00:00+06:00', '2025-01-03T00:00:00+06:00']
24
+ *
25
+ * @example
26
+ * // Using a relative date range with skipDays:
27
+ * new Chronos().getDatesInRange({ span: 7, unit: 'day', skipDays: ['Saturday', 'Sunday'] });
28
+ * // → Array of 7 dates excluding weekends
29
+ *
30
+ * @example
31
+ * // UTC format:
32
+ * new Chronos().getDatesInRange({ span: 2, unit: 'day', format: 'utc' });
33
+ * // → ['2025-06-16T00:00:00.000Z', '2025-06-17T00:00:00.000Z']
34
+ */
35
+ getDatesInRange(options?: RangeWithDates): ISOTimeString[];
36
+ /**
37
+ * @instance Returns an array of ISO date-time strings within a specific date range.
38
+ *
39
+ * - If the input is a fixed range (`from` and `to`), it includes all dates between them.
40
+ * - If the input is a relative range (`span` and `unit`), it starts from current date and goes forward.
41
+ * - If `skipDays` are provided, matching weekdays are excluded from the result.
42
+ *
43
+ * @param options - Configuration for the date range. Accepts a relative (`RelativeDateRange`) format.
44
+ * @returns Array of ISO date-time strings in either local or UTC format, excluding any skipped weekdays if specified.
45
+ *
46
+ * - Please refer to {@link https://toolbox.nazmul-nhb.dev/docs/classes/Chronos/calculation#getdatesinrange docs} for details.
47
+ *
48
+ * @example
49
+ * // Using a relative date range with skipDays:
50
+ * new Chronos().getDatesInRange({ span: 7, unit: 'day', skipDays: ['Saturday', 'Sunday'] });
51
+ * // → Array of 7 dates excluding weekends
52
+ *
53
+ * @example
54
+ * // UTC format:
55
+ * new Chronos().getDatesInRange({ span: 2, unit: 'day', format: 'utc' });
56
+ * // → ['2025-06-16T00:00:00.000Z', '2025-06-17T00:00:00.000Z']
57
+ *
58
+ * @example
59
+ * // Using a fixed date range:
60
+ * new Chronos().getDatesInRange({ from: '2025-01-01', to: '2025-01-03' });
61
+ * // → ['2025-01-01T00:00:00+06:00', '2025-01-02T00:00:00+06:00', '2025-01-03T00:00:00+06:00']
62
+ */
63
+ getDatesInRange(options?: RelativeDateRange): ISOTimeString[];
64
+ }
65
+ }
66
+ /** * Plugin to inject `getDatesInRange` related method */
67
+ export declare const dateRangePlugin: ($Chronos: $Chronos) => void;
@@ -1,5 +1,5 @@
1
1
  import type { $BnOnes, BanglaDigit, Enumerate, LocaleCode, NumberRange } from '../number/types';
2
- import type { Branded, Maybe } from '../types/index';
2
+ import type { Maybe } from '../types/index';
3
3
  import type { LooseLiteral, RangeTuple, Repeat, Split } from '../utils/types';
4
4
  import type { Chronos } from './Chronos';
5
5
  import type { ChronosStatics } from './chronos-statics';
@@ -295,8 +295,8 @@ export type $UTCOffset = `${PositiveUTCHour | NegativeUTCHour}:${UTCMinute}`;
295
295
  export type UTCOffset = `UTC${$UTCOffset}`;
296
296
  /** GMT offset in `GMT±HH:mm` or simply `GMT` format */
297
297
  export type $GMTOffset = `GMT${$UTCOffset}` | 'GMT';
298
- /** Timestamp string type in ISO 8601 format */
299
- export type Timestamp = Branded<string, 'Timestamp'>;
298
+ /** ISO timestamp string type in ISO 8601 format */
299
+ export type ISOTimeString = `${number}-${number}-${number}T${number}:${number}:${number}.${number}${'Z' | $UTCOffset}`;
300
300
  /** Valid argument type accepted by `Date` constructor */
301
301
  export type DateArgs = string | number | Date;
302
302
  /** Type for ISO date format options */
@@ -1,5 +1,5 @@
1
1
  import type { Numeric } from '../types/index';
2
- import type { $TimeZoneIdentifier, ClockTime, DateArgs, DateFormatOptions, HourMinutes, ISODateFormat, TimeOnlyFormat, TimeZoneDetails, TimeZoneIdNative, Timestamp, TimestampOptions, UTCOffset } from './types';
2
+ import type { $TimeZoneIdentifier, ClockTime, DateArgs, DateFormatOptions, HourMinutes, ISODateFormat, ISOTimeString, TimeOnlyFormat, TimestampOptions, TimeZoneDetails, TimeZoneIdNative, UTCOffset } from './types';
3
3
  /**
4
4
  * * Extracts the hour and minute from a time string in `HH:MM` or `-HH:MM` format.
5
5
  *
@@ -117,18 +117,11 @@ export declare function formatDate(options?: DateFormatOptions): string;
117
117
  */
118
118
  export declare function formatTimePart(time: string, format?: TimeOnlyFormat): string;
119
119
  /**
120
- * * Get timestamp in ISO 8601 format.
121
- *
122
- * @param value - Date value to convert to timestamp. Supported formats include:
123
- * - `Date` object → e.g., `new Date()`
124
- * - Date string → e.g., `'2025-04-06'`, `'2025-04-06 16:11:55'`, `'April 6, 2025 16:11:55'` etc.
125
- * - Timestamp number → e.g., `1712748715000`
126
- *
127
- * @remarks If the provided {@link value} is invalid, the current date and time will be used.
120
+ * * Get timestamp in ISO 8601 format for the current date and time.
128
121
  *
129
122
  * @returns Timestamp string in ISO 8601 format.
130
123
  */
131
- export declare function getTimestamp(): Timestamp;
124
+ export declare function getTimestamp(): ISOTimeString;
132
125
  /**
133
126
  * * Get timestamp in ISO 8601 format.
134
127
  *
@@ -144,7 +137,7 @@ export declare function getTimestamp(): Timestamp;
144
137
  *
145
138
  * @returns Timestamp string in ISO 8601 format.
146
139
  */
147
- export declare function getTimestamp(value: DateArgs, format?: ISODateFormat): Timestamp;
140
+ export declare function getTimestamp(value: DateArgs, format?: ISODateFormat): ISOTimeString;
148
141
  /**
149
142
  * * Get timestamp in ISO 8601 format.
150
143
  *
@@ -152,8 +145,8 @@ export declare function getTimestamp(value: DateArgs, format?: ISODateFormat): T
152
145
  *
153
146
  * @remarks
154
147
  * - If the provided {@link TimestampOptions.value value} is invalid, the current date and time will be used.
155
- * - Use `format: 'local'` to include the current system timezone offset.
148
+ * - Use {@link TimestampOptions.format format}: `'local'` to include the current system time & timezone offset.
156
149
  *
157
150
  * @returns Timestamp string in ISO 8601 format.
158
151
  */
159
- export declare function getTimestamp(options?: TimestampOptions): Timestamp;
152
+ export declare function getTimestamp(options: TimestampOptions): ISOTimeString;
@@ -1,5 +1,4 @@
1
1
  var _a;
2
- import { isValidArray } from '../guards/non-primitives.js';
3
2
  import { isNumber, isString } from '../guards/primitives.js';
4
3
  import { DAYS, INTERNALS, MONTHS, MS_PER_DAY } from './constants.js';
5
4
  import { isLeapYear } from './guards.js';
@@ -589,44 +588,6 @@ export class Chronos {
589
588
  monthName(index) {
590
589
  return MONTHS[index ?? this.month];
591
590
  }
592
- getDatesInRange(options) {
593
- let startDate = this.clone(), endDate = this.addWeeks(4);
594
- const { format = 'local', onlyDays, skipDays, roundDate = false } = options ?? {};
595
- if (options) {
596
- if ('from' in options || 'to' in options) {
597
- if (options?.from)
598
- startDate = _a.#cast(options.from);
599
- if (options?.to)
600
- endDate = _a.#cast(options.to);
601
- }
602
- else if ('span' in options || 'unit' in options) {
603
- const { span = 4, unit = 'week' } = options;
604
- endDate = startDate.add(span, unit);
605
- }
606
- }
607
- if (roundDate) {
608
- startDate = startDate.startOf('day');
609
- endDate = endDate.startOf('day');
610
- }
611
- const skipSet = new Set((isValidArray(onlyDays) ? onlyDays
612
- : isValidArray(skipDays) ? skipDays
613
- : []).map((day) => (isNumber(day) ? day : DAYS.indexOf(day))));
614
- const dates = [];
615
- const startTime = startDate.#timestamp;
616
- const endTime = endDate.#timestamp;
617
- const step = (startTime <= endTime ? 1 : -1) * MS_PER_DAY;
618
- const totalDays = Math.floor(Math.abs(endTime - startTime) / MS_PER_DAY);
619
- for (let i = 0; i <= totalDays; i++) {
620
- const ts = startTime + i * step;
621
- const wDay = new Date(ts).getDay();
622
- const include = isValidArray(onlyDays) ? skipSet.has(wDay) : !skipSet.has(wDay);
623
- if (include) {
624
- const chr = new _a(ts).#withOrigin('clone', startDate.#offset, startDate.timeZoneName, startDate.timeZoneId, startDate.$tzTracker);
625
- dates.push(format === 'local' ? chr.toLocalISOString() : chr.toISOString());
626
- }
627
- }
628
- return dates;
629
- }
630
591
  static parse(dateStr, format) {
631
592
  const tokenPatterns = {
632
593
  YYYY: '(?<YYYY>\\d{4})',
@@ -811,9 +772,9 @@ export class Chronos {
811
772
  }
812
773
  const { native, origin, utcOffset, timeZoneName, timeZoneId, $tzTracker } = value;
813
774
  const offsetMins = extractMinutesFromUTC(utcOffset);
814
- const instance = new _a(native);
815
- const diffMins = instance.getTimeZoneOffsetMinutes() - offsetMins;
816
- const target = instance.utcOffset === utcOffset ? instance : instance.add(-diffMins, 'minute');
775
+ const chr = new _a(native);
776
+ const diffMins = chr.getTimeZoneOffsetMinutes() - offsetMins;
777
+ const target = chr.utcOffset === utcOffset ? chr : chr.add(-diffMins, 'minute');
817
778
  return target.#withOrigin(origin, utcOffset, timeZoneName, timeZoneId, $tzTracker);
818
779
  }
819
780
  static use(plugin) {
@@ -0,0 +1,46 @@
1
+ import { isValidArray } from '../../guards/non-primitives.js';
2
+ import { isNumber } from '../../guards/primitives.js';
3
+ import { INTERNALS } from '../Chronos.js';
4
+ import { DAYS, MS_PER_DAY } from '../constants.js';
5
+ export const dateRangePlugin = ($Chronos) => {
6
+ const { internalDate: $Date, cast, withOrigin, offset } = $Chronos[INTERNALS];
7
+ $Chronos.prototype.getDatesInRange = function (options) {
8
+ let startDate = this.clone(), endDate = this.addWeeks(4);
9
+ const { format = 'local', onlyDays, skipDays, roundDate = false } = options ?? {};
10
+ if (options) {
11
+ if ('from' in options || 'to' in options) {
12
+ if (options?.from)
13
+ startDate = cast(options.from);
14
+ if (options?.to)
15
+ endDate = cast(options.to);
16
+ }
17
+ else if ('span' in options || 'unit' in options) {
18
+ const { span = 4, unit = 'week' } = options;
19
+ endDate = startDate.add(span, unit);
20
+ }
21
+ }
22
+ if (roundDate) {
23
+ startDate = startDate.startOf('day');
24
+ endDate = endDate.startOf('day');
25
+ }
26
+ const skippedDays = isValidArray(onlyDays) ? onlyDays
27
+ : isValidArray(skipDays) ? skipDays
28
+ : [];
29
+ const skipSet = new Set(skippedDays.map((day) => (isNumber(day) ? day : DAYS.indexOf(day))));
30
+ const dates = [];
31
+ const startTime = $Date(startDate).getTime();
32
+ const endTime = $Date(endDate).getTime();
33
+ const step = (startTime <= endTime ? 1 : -1) * MS_PER_DAY;
34
+ const totalDays = Math.floor(Math.abs(endTime - startTime) / MS_PER_DAY);
35
+ for (let i = 0; i <= totalDays; i++) {
36
+ const ts = startTime + i * step;
37
+ const wDay = new Date(ts).getDay();
38
+ const include = isValidArray(onlyDays) ? skipSet.has(wDay) : !skipSet.has(wDay);
39
+ if (include) {
40
+ const chr = withOrigin(new $Chronos(ts), 'clone', offset(this), startDate.timeZoneName, startDate.timeZoneId, startDate.$tzTracker);
41
+ dates.push(format === 'local' ? chr.toLocalISOString() : chr.toISOString());
42
+ }
43
+ }
44
+ return dates;
45
+ };
46
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nhb-toolbox",
3
- "version": "4.28.71",
3
+ "version": "4.28.80",
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",
@@ -253,6 +253,11 @@
253
253
  "import": "./dist/esm/date/plugins/businessPlugin.js",
254
254
  "require": "./dist/cjs/date/plugins/businessPlugin.js"
255
255
  },
256
+ "./plugins/dateRangePlugin": {
257
+ "types": "./dist/dts/date/plugins/dateRangePlugin.d.ts",
258
+ "import": "./dist/esm/date/plugins/dateRangePlugin.js",
259
+ "require": "./dist/cjs/date/plugins/dateRangePlugin.js"
260
+ },
256
261
  "./plugins/dayPartPlugin": {
257
262
  "types": "./dist/dts/date/plugins/dayPartPlugin.d.ts",
258
263
  "import": "./dist/esm/date/plugins/dayPartPlugin.js",
@@ -387,6 +392,9 @@
387
392
  "plugins/businessPlugin": [
388
393
  "dist/dts/date/plugins/businessPlugin.d.ts"
389
394
  ],
395
+ "plugins/dateRangePlugin": [
396
+ "dist/dts/date/plugins/dateRangePlugin.d.ts"
397
+ ],
390
398
  "plugins/dayPartPlugin": [
391
399
  "dist/dts/date/plugins/dayPartPlugin.d.ts"
392
400
  ],