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 +11 -0
- package/README.md +5 -5
- package/dist/cjs/date/Chronos.js +3 -42
- package/dist/cjs/date/plugins/dateRangePlugin.js +50 -0
- package/dist/dts/date/Chronos.d.ts +3 -63
- package/dist/dts/date/constants.d.ts +1 -1
- package/dist/dts/date/plugins/dateRangePlugin.d.ts +67 -0
- package/dist/dts/date/types.d.ts +3 -3
- package/dist/dts/date/utils.d.ts +6 -13
- package/dist/esm/date/Chronos.js +3 -42
- package/dist/esm/date/plugins/dateRangePlugin.js +46 -0
- package/package.json +9 -1
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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>
|
package/dist/cjs/date/Chronos.js
CHANGED
|
@@ -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
|
|
818
|
-
const diffMins =
|
|
819
|
-
const target =
|
|
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,
|
|
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():
|
|
211
|
+
toLocalISOString(): ISOTimeString;
|
|
212
212
|
/** @instance Returns a date as a string value in ISO format (UTC). */
|
|
213
|
-
toISOString():
|
|
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" | "
|
|
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;
|
package/dist/dts/date/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { $BnOnes, BanglaDigit, Enumerate, LocaleCode, NumberRange } from '../number/types';
|
|
2
|
-
import type {
|
|
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
|
-
/**
|
|
299
|
-
export type
|
|
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 */
|
package/dist/dts/date/utils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Numeric } from '../types/index';
|
|
2
|
-
import type { $TimeZoneIdentifier, ClockTime, DateArgs, DateFormatOptions, HourMinutes, ISODateFormat,
|
|
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():
|
|
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):
|
|
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
|
|
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
|
|
152
|
+
export declare function getTimestamp(options: TimestampOptions): ISOTimeString;
|
package/dist/esm/date/Chronos.js
CHANGED
|
@@ -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
|
|
815
|
-
const diffMins =
|
|
816
|
-
const target =
|
|
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.
|
|
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
|
],
|