@org-quicko/core 2.0.5 → 2.0.6
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/README.md +37 -14
- package/dist/browser/utils/date/DateUtil.js +19 -16
- package/dist/browser/utils/date/DateUtil.js.map +1 -1
- package/dist/cjs/utils/date/DateUtil.cjs +19 -16
- package/dist/cjs/utils/date/DateUtil.cjs.map +1 -1
- package/dist/esm/utils/date/DateUtil.js +19 -16
- package/dist/esm/utils/date/DateUtil.js.map +1 -1
- package/dist/types/src/utils/date/DateUtil.d.ts +1 -0
- package/package.json +9 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# core
|
|
1
|
+
# @org-quicko/core
|
|
2
2
|
|
|
3
|
-
Foundational
|
|
3
|
+
Foundational TypeScript library used across Quicko for shared beans, types, utilities, logger helpers, and exceptions.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -8,26 +8,49 @@ Foundational Node.js library built with TypeScript used across Quicko.
|
|
|
8
8
|
npm install @org-quicko/core
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
## Local Development
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm ci
|
|
15
|
+
npm run lint
|
|
16
|
+
npm run build
|
|
17
|
+
npm run test
|
|
18
|
+
```
|
|
19
|
+
|
|
11
20
|
## Release Flow
|
|
12
21
|
|
|
13
|
-
This
|
|
22
|
+
This repo uses GitHub Actions for:
|
|
23
|
+
|
|
24
|
+
- pull request validation
|
|
25
|
+
- release drafting on `main`
|
|
26
|
+
- npm publish when a GitHub release is published
|
|
14
27
|
|
|
15
|
-
|
|
16
|
-
- Pushes to `main` update the next draft release using Release Drafter.
|
|
17
|
-
- Publishing happens only when a GitHub release is published.
|
|
18
|
-
- PR titles are used directly in the drafted release notes, so keep them clear and specific.
|
|
19
|
-
- PR labels influence both release note grouping and version bump resolution.
|
|
28
|
+
PR titles are used in release notes, and labels (`major`, `minor`, `patch`) drive the draft version bump.
|
|
20
29
|
|
|
21
|
-
|
|
30
|
+
## Publishing
|
|
22
31
|
|
|
23
|
-
1. Update
|
|
32
|
+
1. Update `package.json` version.
|
|
24
33
|
2. Merge the change into `main`.
|
|
25
|
-
3. Review the
|
|
26
|
-
4. Publish the release with a tag that matches the package version
|
|
34
|
+
3. Review the draft release on GitHub.
|
|
35
|
+
4. Publish the release with a tag that matches the package version.
|
|
36
|
+
|
|
37
|
+
Example:
|
|
38
|
+
|
|
39
|
+
- `package.json`: `2.0.5`
|
|
40
|
+
- release tag: `v2.0.5`
|
|
27
41
|
|
|
28
42
|
When the release is published, GitHub Actions will:
|
|
29
43
|
|
|
30
|
-
- verify the release tag matches `package.json`
|
|
31
44
|
- run install, tests, and build
|
|
32
45
|
- skip publish if that version already exists on npm
|
|
33
|
-
- publish
|
|
46
|
+
- publish to npm with provenance enabled
|
|
47
|
+
|
|
48
|
+
## Requirements
|
|
49
|
+
|
|
50
|
+
- GitHub Actions secret: `NPM_TOKEN`
|
|
51
|
+
- correct `package.json` metadata:
|
|
52
|
+
- `repository.url`
|
|
53
|
+
- `homepage`
|
|
54
|
+
- `bugs.url`
|
|
55
|
+
|
|
56
|
+
If repository metadata does not match `https://github.com/org-quicko/core-js`, npm provenance validation can fail.
|
|
@@ -40,15 +40,15 @@ class DateUtil {
|
|
|
40
40
|
return date;
|
|
41
41
|
}
|
|
42
42
|
static printDate(date, timeZone, dateFormat = this.ISO_8601_FORMAT) {
|
|
43
|
-
const normalizedDate =
|
|
43
|
+
const normalizedDate = this.normalizeDate(date);
|
|
44
44
|
return format(new TZDate(normalizedDate, timeZone), dateFormat);
|
|
45
45
|
}
|
|
46
46
|
static getStartOfDay(date, timeZone) {
|
|
47
|
-
const normalizedDate =
|
|
47
|
+
const normalizedDate = this.normalizeDate(date);
|
|
48
48
|
return startOfDay(new TZDate(normalizedDate, timeZone));
|
|
49
49
|
}
|
|
50
50
|
static getEndOfDay(date, timeZone) {
|
|
51
|
-
const normalizedDate =
|
|
51
|
+
const normalizedDate = this.normalizeDate(date);
|
|
52
52
|
return endOfDay(new TZDate(normalizedDate, timeZone));
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
@@ -67,40 +67,40 @@ class DateUtil {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
static daysInBetween(firstDate, secondDate, timeZone) {
|
|
70
|
-
const first =
|
|
71
|
-
const second =
|
|
70
|
+
const first = this.normalizeDate(firstDate);
|
|
71
|
+
const second = this.normalizeDate(secondDate);
|
|
72
72
|
const effectiveTimeZone = timeZone || this.TIMEZONE;
|
|
73
73
|
return Math.abs(differenceInCalendarDays(new TZDate(first, effectiveTimeZone), new TZDate(second, effectiveTimeZone)));
|
|
74
74
|
}
|
|
75
75
|
static monthsInBetween(firstDate, secondDate, timeZone) {
|
|
76
|
-
const first =
|
|
77
|
-
const second =
|
|
76
|
+
const first = this.normalizeDate(firstDate);
|
|
77
|
+
const second = this.normalizeDate(secondDate);
|
|
78
78
|
const effectiveTimeZone = timeZone || this.TIMEZONE;
|
|
79
79
|
return Math.abs(differenceInCalendarMonths(new TZDate(first, effectiveTimeZone), new TZDate(second, effectiveTimeZone)));
|
|
80
80
|
}
|
|
81
81
|
static yearsInBetween(firstDate, secondDate, timeZone) {
|
|
82
|
-
const first =
|
|
83
|
-
const second =
|
|
82
|
+
const first = this.normalizeDate(firstDate);
|
|
83
|
+
const second = this.normalizeDate(secondDate);
|
|
84
84
|
const effectiveTimeZone = timeZone || this.TIMEZONE;
|
|
85
85
|
return Math.abs(differenceInCalendarYears(new TZDate(first, effectiveTimeZone), new TZDate(second, effectiveTimeZone)));
|
|
86
86
|
}
|
|
87
87
|
static hoursInBetween(firstDate, secondDate) {
|
|
88
|
-
const first =
|
|
89
|
-
const second =
|
|
88
|
+
const first = this.normalizeDate(firstDate);
|
|
89
|
+
const second = this.normalizeDate(secondDate);
|
|
90
90
|
return Math.abs(differenceInHours(first, second));
|
|
91
91
|
}
|
|
92
92
|
static secondsInBetween(firstDate, secondDate) {
|
|
93
|
-
const first =
|
|
94
|
-
const second =
|
|
93
|
+
const first = this.normalizeDate(firstDate);
|
|
94
|
+
const second = this.normalizeDate(secondDate);
|
|
95
95
|
return Math.abs(differenceInSeconds(first, second));
|
|
96
96
|
}
|
|
97
97
|
static compareDates(firstDate, secondDate) {
|
|
98
|
-
const first =
|
|
99
|
-
const second =
|
|
98
|
+
const first = this.normalizeDate(firstDate);
|
|
99
|
+
const second = this.normalizeDate(secondDate);
|
|
100
100
|
return compareAsc(first, second);
|
|
101
101
|
}
|
|
102
102
|
static addDuration(date, duration, timeZone) {
|
|
103
|
-
const normalizedDate =
|
|
103
|
+
const normalizedDate = this.normalizeDate(date);
|
|
104
104
|
const effectiveTimeZone = timeZone || this.TIMEZONE;
|
|
105
105
|
return add(new TZDate(normalizedDate, effectiveTimeZone), duration);
|
|
106
106
|
}
|
|
@@ -120,6 +120,9 @@ class DateUtil {
|
|
|
120
120
|
static fromMillis(milliseconds) {
|
|
121
121
|
return new Date(milliseconds);
|
|
122
122
|
}
|
|
123
|
+
static normalizeDate(date) {
|
|
124
|
+
return typeof date === 'number' ? this.fromMillis(date) : date;
|
|
125
|
+
}
|
|
123
126
|
/**
|
|
124
127
|
* Converts a Date object to a timestamp (in milliseconds).
|
|
125
128
|
* @param date The Date object to convert.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateUtil.js","sources":["../../../../src/utils/date/DateUtil.ts"],"sourcesContent":["import { TZDate } from '@date-fns/tz';\nimport { add, compareAsc, differenceInCalendarDays, differenceInCalendarMonths, differenceInCalendarYears, differenceInHours, differenceInSeconds, Duration, endOfDay, format, isLeapYear, isValid, parse, startOfDay } from 'date-fns';\nimport { IllegalArgumentException } from '../../exceptions';\n\n/**\n * Utility class for date and time operations. Provides methods for parsing,\n * formatting, and performing calculations with dates and times.\n */\nexport class DateUtil {\n\n static readonly ISO_8601_FORMAT = \"yyyy-MM-dd'T'HH:mm:ss.SSSxxx\"\n static readonly TIMEZONE = \"UTC\"\n\n /**\n * Gets the current date and time in the specified time zone.\n * @param timeZone The IANA time zone identifier.\n * @returns Current date and time in the specified time zone.\n */\n static now(timeZone: string): Date {\n return new TZDate(new Date(), timeZone);\n }\n\n /**\n * Gets the current time in milliseconds since the Unix epoch.\n * @returns Current time in milliseconds.\n */\n static nowInMillis(): number {\n return Date.now();\n }\n\n /**\n * Parses a date string into a Date object.\n * @param dateString The date string to parse.\n * @param dateFormat The format of the date string (default: ISO_8601_FORMAT).\n * @param timeZone The IANA time zone identifier.\n * @throws {IllegalArgumentException} If the date string is invalid.\n * @returns Parsed Date object.\n */\n static readDate(dateString: string, dateFormat = this.ISO_8601_FORMAT, timeZone: string): Date {\n const date = parse(dateString, dateFormat, TZDate.tz(timeZone));\n if (!isValid(date)) {\n throw new IllegalArgumentException('Invalid date string or date format');\n }\n return date;\n }\n\n /**\n * Formats a Date or timestamp into a string.\n * @param date The date or timestamp to format.\n * @param timeZone The IANA time zone identifier.\n * @param dateFormat The desired output format (default: ISO_8601_FORMAT).\n * @returns Formatted date string.\n */\n static printDate(date: Date, timeZone: string, dateFormat?: string): string;\n static printDate(date: number, timeZone: string, dateFormat?: string): string;\n static printDate(date: Date | number, timeZone: string, dateFormat: string = this.ISO_8601_FORMAT): string {\n const normalizedDate = typeof date === 'number' ? DateUtil.fromMillis(date) : date;\n return format(new TZDate(normalizedDate, timeZone), dateFormat);\n }\n\n /**\n * Gets the start of the day for a given date or timestamp.\n * @param date The date or timestamp to calculate from.\n * @param timeZone The IANA time zone identifier.\n * @returns The start of the day as a Date object.\n */\n static getStartOfDay(date: Date, timeZone: string): Date;\n static getStartOfDay(date: number, timeZone: string): Date;\n static getStartOfDay(date: Date | number, timeZone: string): Date {\n const normalizedDate = typeof date === 'number' ? DateUtil.fromMillis(date) : date;\n return startOfDay(new TZDate(normalizedDate, timeZone));\n }\n\n /**\n * Gets the end of the day for a given date or timestamp.\n * @param date The date or timestamp to calculate from.\n * @param timeZone The IANA time zone identifier.\n * @returns The end of the day as a Date object.\n */\n static getEndOfDay(date: Date, timeZone: string): Date;\n static getEndOfDay(date: number, timeZone: string): Date;\n static getEndOfDay(date: Date | number, timeZone: string): Date {\n const normalizedDate = typeof date === 'number' ? DateUtil.fromMillis(date) : date;\n return endOfDay(new TZDate(normalizedDate, timeZone));\n }\n\n /**\n * Checks if a date string is valid according to the specified format.\n * @param dateString The date string to validate.\n * @param dateFormat Optional date format (default: ISO_8601_FORMAT).\n * @returns True if the date is valid, false otherwise.\n */\n static isValidDate(dateString: string, dateFormat?: string): boolean {\n try {\n DateUtil.readDate(dateString, dateFormat, \"UTC\");\n return true;\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Calculates the absolute number of calendar days between two dates or timestamps.\n * Since day boundaries depend on a calendar, callers can optionally provide a time zone\n * so the same pair of instants is interpreted consistently across machines.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @param timeZone Optional IANA time zone identifier used for calendar comparisons.\n * @returns Number of days between the two dates.\n */\n static daysInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number;\n static daysInBetween(firstDate: number, secondDate: number, timeZone?: string): number;\n static daysInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number {\n const first = typeof firstDate === 'number' ? DateUtil.fromMillis(firstDate) : firstDate;\n const second = typeof secondDate === 'number' ? DateUtil.fromMillis(secondDate) : secondDate;\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return Math.abs(\n differenceInCalendarDays(\n new TZDate(first, effectiveTimeZone),\n new TZDate(second, effectiveTimeZone),\n )\n );\n }\n\n /**\n * Calculates the absolute number of calendar months between two dates or timestamps.\n * Since month boundaries depend on a calendar, callers can optionally provide a time zone\n * so the same pair of instants is interpreted consistently across machines.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @param timeZone Optional IANA time zone identifier used for calendar comparisons.\n * @returns The number of months between the two dates.\n */\n static monthsInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number;\n static monthsInBetween(firstDate: number, secondDate: number, timeZone?: string): number;\n static monthsInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number {\n const first = typeof firstDate === 'number' ? DateUtil.fromMillis(firstDate) : firstDate;\n const second = typeof secondDate === 'number' ? DateUtil.fromMillis(secondDate) : secondDate;\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return Math.abs(\n differenceInCalendarMonths(\n new TZDate(first, effectiveTimeZone),\n new TZDate(second, effectiveTimeZone),\n )\n );\n }\n\n /**\n * Calculates the absolute number of calendar years between two dates or timestamps.\n * Since year boundaries depend on a calendar, callers can optionally provide a time zone\n * so the same pair of instants is interpreted consistently across machines.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @param timeZone Optional IANA time zone identifier used for calendar comparisons.\n * @returns The number of years between the two dates.\n */\n static yearsInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number;\n static yearsInBetween(firstDate: number, secondDate: number, timeZone?: string): number;\n static yearsInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number {\n const first = typeof firstDate === 'number' ? DateUtil.fromMillis(firstDate) : firstDate;\n const second = typeof secondDate === 'number' ? DateUtil.fromMillis(secondDate) : secondDate;\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return Math.abs(\n differenceInCalendarYears(\n new TZDate(first, effectiveTimeZone),\n new TZDate(second, effectiveTimeZone),\n )\n );\n }\n\n /**\n * Calculates the absolute elapsed number of hours between two dates or timestamps.\n * This is duration-based, not calendar-based, so it is independent of time zone.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @returns The number of hours between the two dates.\n */\n static hoursInBetween(firstDate: Date, secondDate: Date): number;\n static hoursInBetween(firstDate: number, secondDate: number): number;\n static hoursInBetween(firstDate: Date | number, secondDate: Date | number): number {\n const first = typeof firstDate === 'number' ? DateUtil.fromMillis(firstDate) : firstDate;\n const second = typeof secondDate === 'number' ? DateUtil.fromMillis(secondDate) : secondDate;\n return Math.abs(differenceInHours(first, second));\n }\n\n /**\n * Calculates the absolute elapsed number of seconds between two dates or timestamps.\n * This is duration-based, not calendar-based, so it is independent of time zone.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @returns The number of seconds between the two dates.\n */\n static secondsInBetween(firstDate: Date, secondDate: Date): number;\n static secondsInBetween(firstDate: number, secondDate: number): number;\n static secondsInBetween(firstDate: Date | number, secondDate: Date | number): number {\n const first = typeof firstDate === 'number' ? DateUtil.fromMillis(firstDate) : firstDate;\n const second = typeof secondDate === 'number' ? DateUtil.fromMillis(secondDate) : secondDate;\n return Math.abs(differenceInSeconds(first, second));\n }\n\n /**\n * Compares two dates or timestamps.\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @returns `-1` if the first date is earlier, `1` if it is later, or `0` if the two dates are equal.\n */\n static compareDates(firstDate: Date, secondDate: Date): -1 | 0 | 1;\n static compareDates(firstDate: number, secondDate: number): -1 | 0 | 1;\n static compareDates(firstDate: Date | number, secondDate: Date | number): -1 | 0 | 1 {\n const first = typeof firstDate === 'number' ? DateUtil.fromMillis(firstDate) : firstDate;\n const second = typeof secondDate === 'number' ? DateUtil.fromMillis(secondDate) : secondDate;\n\n return compareAsc(first, second) as -1 | 0 | 1;\n }\n\n /**\n * Adds a duration (e.g., days, months, years) to a given date or timestamp.\n * When a time zone is provided, the duration is applied using calendar arithmetic\n * in that time zone so month-end or day-boundary business rules stay aligned locally.\n *\n * @param date The base date or timestamp to which the duration will be added.\n * @param duration An object specifying the duration (e.g., `{ days: 1, months: 2 }`).\n * @param timeZone Optional IANA time zone identifier used for calendar math.\n * @returns A new Date object with the duration added.\n */\n static addDuration(date: Date, duration: Duration, timeZone?: string): Date;\n static addDuration(date: number, duration: Duration, timeZone?: string): Date;\n static addDuration(date: Date | number, duration: Duration, timeZone?: string): Date {\n const normalizedDate = typeof date === 'number' ? DateUtil.fromMillis(date) : date;\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return add(new TZDate(normalizedDate, effectiveTimeZone), duration);\n }\n\n /**\n * Determines whether a given year is a leap year.\n * @param year The year to check.\n * @returns `true` if the year is a leap year, otherwise `false`.\n */\n static isLeapYear(year: number): boolean {\n return isLeapYear(DateUtil.readDate(year.toString(), 'yyyy', \"UTC\"));\n }\n\n\n /**\n * Converts a timestamp (in milliseconds) to a Date object.\n * @param milliseconds The timestamp in milliseconds since the Unix epoch.\n * @returns A Date object representing the provided timestamp.\n */\n static fromMillis(milliseconds: number): Date {\n return new Date(milliseconds);\n }\n\n /**\n * Converts a Date object to a timestamp (in milliseconds).\n * @param date The Date object to convert.\n * @returns The timestamp in milliseconds since the Unix epoch.\n */\n static toMillis(date: Date): number {\n return date.getTime();\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DateUtil.js","sources":["../../../../src/utils/date/DateUtil.ts"],"sourcesContent":["import { TZDate } from '@date-fns/tz';\nimport { add, compareAsc, differenceInCalendarDays, differenceInCalendarMonths, differenceInCalendarYears, differenceInHours, differenceInSeconds, Duration, endOfDay, format, isLeapYear, isValid, parse, startOfDay } from 'date-fns';\nimport { IllegalArgumentException } from '../../exceptions';\n\n/**\n * Utility class for date and time operations. Provides methods for parsing,\n * formatting, and performing calculations with dates and times.\n */\nexport class DateUtil {\n\n static readonly ISO_8601_FORMAT = \"yyyy-MM-dd'T'HH:mm:ss.SSSxxx\"\n static readonly TIMEZONE = \"UTC\"\n\n /**\n * Gets the current date and time in the specified time zone.\n * @param timeZone The IANA time zone identifier.\n * @returns Current date and time in the specified time zone.\n */\n static now(timeZone: string): Date {\n return new TZDate(new Date(), timeZone);\n }\n\n /**\n * Gets the current time in milliseconds since the Unix epoch.\n * @returns Current time in milliseconds.\n */\n static nowInMillis(): number {\n return Date.now();\n }\n\n /**\n * Parses a date string into a Date object.\n * @param dateString The date string to parse.\n * @param dateFormat The format of the date string (default: ISO_8601_FORMAT).\n * @param timeZone The IANA time zone identifier.\n * @throws {IllegalArgumentException} If the date string is invalid.\n * @returns Parsed Date object.\n */\n static readDate(dateString: string, dateFormat = this.ISO_8601_FORMAT, timeZone: string): Date {\n const date = parse(dateString, dateFormat, TZDate.tz(timeZone));\n if (!isValid(date)) {\n throw new IllegalArgumentException('Invalid date string or date format');\n }\n return date;\n }\n\n /**\n * Formats a Date or timestamp into a string.\n * @param date The date or timestamp to format.\n * @param timeZone The IANA time zone identifier.\n * @param dateFormat The desired output format (default: ISO_8601_FORMAT).\n * @returns Formatted date string.\n */\n static printDate(date: Date, timeZone: string, dateFormat?: string): string;\n static printDate(date: number, timeZone: string, dateFormat?: string): string;\n static printDate(date: Date | number, timeZone: string, dateFormat: string = this.ISO_8601_FORMAT): string {\n const normalizedDate = this.normalizeDate(date);\n return format(new TZDate(normalizedDate, timeZone), dateFormat);\n }\n\n /**\n * Gets the start of the day for a given date or timestamp.\n * @param date The date or timestamp to calculate from.\n * @param timeZone The IANA time zone identifier.\n * @returns The start of the day as a Date object.\n */\n static getStartOfDay(date: Date, timeZone: string): Date;\n static getStartOfDay(date: number, timeZone: string): Date;\n static getStartOfDay(date: Date | number, timeZone: string): Date {\n const normalizedDate = this.normalizeDate(date);\n return startOfDay(new TZDate(normalizedDate, timeZone));\n }\n\n /**\n * Gets the end of the day for a given date or timestamp.\n * @param date The date or timestamp to calculate from.\n * @param timeZone The IANA time zone identifier.\n * @returns The end of the day as a Date object.\n */\n static getEndOfDay(date: Date, timeZone: string): Date;\n static getEndOfDay(date: number, timeZone: string): Date;\n static getEndOfDay(date: Date | number, timeZone: string): Date {\n const normalizedDate = this.normalizeDate(date);\n return endOfDay(new TZDate(normalizedDate, timeZone));\n }\n\n /**\n * Checks if a date string is valid according to the specified format.\n * @param dateString The date string to validate.\n * @param dateFormat Optional date format (default: ISO_8601_FORMAT).\n * @returns True if the date is valid, false otherwise.\n */\n static isValidDate(dateString: string, dateFormat?: string): boolean {\n try {\n DateUtil.readDate(dateString, dateFormat, \"UTC\");\n return true;\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Calculates the absolute number of calendar days between two dates or timestamps.\n * Since day boundaries depend on a calendar, callers can optionally provide a time zone\n * so the same pair of instants is interpreted consistently across machines.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @param timeZone Optional IANA time zone identifier used for calendar comparisons.\n * @returns Number of days between the two dates.\n */\n static daysInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number;\n static daysInBetween(firstDate: number, secondDate: number, timeZone?: string): number;\n static daysInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number {\n const first = this.normalizeDate(firstDate);\n const second = this.normalizeDate(secondDate);\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return Math.abs(\n differenceInCalendarDays(\n new TZDate(first, effectiveTimeZone),\n new TZDate(second, effectiveTimeZone),\n )\n );\n }\n\n /**\n * Calculates the absolute number of calendar months between two dates or timestamps.\n * Since month boundaries depend on a calendar, callers can optionally provide a time zone\n * so the same pair of instants is interpreted consistently across machines.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @param timeZone Optional IANA time zone identifier used for calendar comparisons.\n * @returns The number of months between the two dates.\n */\n static monthsInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number;\n static monthsInBetween(firstDate: number, secondDate: number, timeZone?: string): number;\n static monthsInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number {\n const first = this.normalizeDate(firstDate);\n const second = this.normalizeDate(secondDate);\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return Math.abs(\n differenceInCalendarMonths(\n new TZDate(first, effectiveTimeZone),\n new TZDate(second, effectiveTimeZone),\n )\n );\n }\n\n /**\n * Calculates the absolute number of calendar years between two dates or timestamps.\n * Since year boundaries depend on a calendar, callers can optionally provide a time zone\n * so the same pair of instants is interpreted consistently across machines.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @param timeZone Optional IANA time zone identifier used for calendar comparisons.\n * @returns The number of years between the two dates.\n */\n static yearsInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number;\n static yearsInBetween(firstDate: number, secondDate: number, timeZone?: string): number;\n static yearsInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number {\n const first = this.normalizeDate(firstDate);\n const second = this.normalizeDate(secondDate);\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return Math.abs(\n differenceInCalendarYears(\n new TZDate(first, effectiveTimeZone),\n new TZDate(second, effectiveTimeZone),\n )\n );\n }\n\n /**\n * Calculates the absolute elapsed number of hours between two dates or timestamps.\n * This is duration-based, not calendar-based, so it is independent of time zone.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @returns The number of hours between the two dates.\n */\n static hoursInBetween(firstDate: Date, secondDate: Date): number;\n static hoursInBetween(firstDate: number, secondDate: number): number;\n static hoursInBetween(firstDate: Date | number, secondDate: Date | number): number {\n const first = this.normalizeDate(firstDate);\n const second = this.normalizeDate(secondDate);\n return Math.abs(differenceInHours(first, second));\n }\n\n /**\n * Calculates the absolute elapsed number of seconds between two dates or timestamps.\n * This is duration-based, not calendar-based, so it is independent of time zone.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @returns The number of seconds between the two dates.\n */\n static secondsInBetween(firstDate: Date, secondDate: Date): number;\n static secondsInBetween(firstDate: number, secondDate: number): number;\n static secondsInBetween(firstDate: Date | number, secondDate: Date | number): number {\n const first = this.normalizeDate(firstDate);\n const second = this.normalizeDate(secondDate);\n return Math.abs(differenceInSeconds(first, second));\n }\n\n /**\n * Compares two dates or timestamps.\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @returns `-1` if the first date is earlier, `1` if it is later, or `0` if the two dates are equal.\n */\n static compareDates(firstDate: Date, secondDate: Date): -1 | 0 | 1;\n static compareDates(firstDate: number, secondDate: number): -1 | 0 | 1;\n static compareDates(firstDate: Date | number, secondDate: Date | number): -1 | 0 | 1 {\n const first = this.normalizeDate(firstDate);\n const second = this.normalizeDate(secondDate);\n\n return compareAsc(first, second) as -1 | 0 | 1;\n }\n\n /**\n * Adds a duration (e.g., days, months, years) to a given date or timestamp.\n * When a time zone is provided, the duration is applied using calendar arithmetic\n * in that time zone so month-end or day-boundary business rules stay aligned locally.\n *\n * @param date The base date or timestamp to which the duration will be added.\n * @param duration An object specifying the duration (e.g., `{ days: 1, months: 2 }`).\n * @param timeZone Optional IANA time zone identifier used for calendar math.\n * @returns A new Date object with the duration added.\n */\n static addDuration(date: Date, duration: Duration, timeZone?: string): Date;\n static addDuration(date: number, duration: Duration, timeZone?: string): Date;\n static addDuration(date: Date | number, duration: Duration, timeZone?: string): Date {\n const normalizedDate = this.normalizeDate(date);\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return add(new TZDate(normalizedDate, effectiveTimeZone), duration);\n }\n\n /**\n * Determines whether a given year is a leap year.\n * @param year The year to check.\n * @returns `true` if the year is a leap year, otherwise `false`.\n */\n static isLeapYear(year: number): boolean {\n return isLeapYear(DateUtil.readDate(year.toString(), 'yyyy', \"UTC\"));\n }\n\n\n /**\n * Converts a timestamp (in milliseconds) to a Date object.\n * @param milliseconds The timestamp in milliseconds since the Unix epoch.\n * @returns A Date object representing the provided timestamp.\n */\n static fromMillis(milliseconds: number): Date {\n return new Date(milliseconds);\n }\n\n protected static normalizeDate(date: Date | number): Date {\n return typeof date === 'number' ? this.fromMillis(date) : date;\n }\n\n /**\n * Converts a Date object to a timestamp (in milliseconds).\n * @param date The Date object to convert.\n * @returns The timestamp in milliseconds since the Unix epoch.\n */\n static toMillis(date: Date): number {\n return date.getTime();\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -42,15 +42,15 @@ class DateUtil {
|
|
|
42
42
|
return date;
|
|
43
43
|
}
|
|
44
44
|
static printDate(date, timeZone, dateFormat = this.ISO_8601_FORMAT) {
|
|
45
|
-
const normalizedDate =
|
|
45
|
+
const normalizedDate = this.normalizeDate(date);
|
|
46
46
|
return dateFns.format(new tz.TZDate(normalizedDate, timeZone), dateFormat);
|
|
47
47
|
}
|
|
48
48
|
static getStartOfDay(date, timeZone) {
|
|
49
|
-
const normalizedDate =
|
|
49
|
+
const normalizedDate = this.normalizeDate(date);
|
|
50
50
|
return dateFns.startOfDay(new tz.TZDate(normalizedDate, timeZone));
|
|
51
51
|
}
|
|
52
52
|
static getEndOfDay(date, timeZone) {
|
|
53
|
-
const normalizedDate =
|
|
53
|
+
const normalizedDate = this.normalizeDate(date);
|
|
54
54
|
return dateFns.endOfDay(new tz.TZDate(normalizedDate, timeZone));
|
|
55
55
|
}
|
|
56
56
|
/**
|
|
@@ -69,40 +69,40 @@ class DateUtil {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
static daysInBetween(firstDate, secondDate, timeZone) {
|
|
72
|
-
const first =
|
|
73
|
-
const second =
|
|
72
|
+
const first = this.normalizeDate(firstDate);
|
|
73
|
+
const second = this.normalizeDate(secondDate);
|
|
74
74
|
const effectiveTimeZone = timeZone || this.TIMEZONE;
|
|
75
75
|
return Math.abs(dateFns.differenceInCalendarDays(new tz.TZDate(first, effectiveTimeZone), new tz.TZDate(second, effectiveTimeZone)));
|
|
76
76
|
}
|
|
77
77
|
static monthsInBetween(firstDate, secondDate, timeZone) {
|
|
78
|
-
const first =
|
|
79
|
-
const second =
|
|
78
|
+
const first = this.normalizeDate(firstDate);
|
|
79
|
+
const second = this.normalizeDate(secondDate);
|
|
80
80
|
const effectiveTimeZone = timeZone || this.TIMEZONE;
|
|
81
81
|
return Math.abs(dateFns.differenceInCalendarMonths(new tz.TZDate(first, effectiveTimeZone), new tz.TZDate(second, effectiveTimeZone)));
|
|
82
82
|
}
|
|
83
83
|
static yearsInBetween(firstDate, secondDate, timeZone) {
|
|
84
|
-
const first =
|
|
85
|
-
const second =
|
|
84
|
+
const first = this.normalizeDate(firstDate);
|
|
85
|
+
const second = this.normalizeDate(secondDate);
|
|
86
86
|
const effectiveTimeZone = timeZone || this.TIMEZONE;
|
|
87
87
|
return Math.abs(dateFns.differenceInCalendarYears(new tz.TZDate(first, effectiveTimeZone), new tz.TZDate(second, effectiveTimeZone)));
|
|
88
88
|
}
|
|
89
89
|
static hoursInBetween(firstDate, secondDate) {
|
|
90
|
-
const first =
|
|
91
|
-
const second =
|
|
90
|
+
const first = this.normalizeDate(firstDate);
|
|
91
|
+
const second = this.normalizeDate(secondDate);
|
|
92
92
|
return Math.abs(dateFns.differenceInHours(first, second));
|
|
93
93
|
}
|
|
94
94
|
static secondsInBetween(firstDate, secondDate) {
|
|
95
|
-
const first =
|
|
96
|
-
const second =
|
|
95
|
+
const first = this.normalizeDate(firstDate);
|
|
96
|
+
const second = this.normalizeDate(secondDate);
|
|
97
97
|
return Math.abs(dateFns.differenceInSeconds(first, second));
|
|
98
98
|
}
|
|
99
99
|
static compareDates(firstDate, secondDate) {
|
|
100
|
-
const first =
|
|
101
|
-
const second =
|
|
100
|
+
const first = this.normalizeDate(firstDate);
|
|
101
|
+
const second = this.normalizeDate(secondDate);
|
|
102
102
|
return dateFns.compareAsc(first, second);
|
|
103
103
|
}
|
|
104
104
|
static addDuration(date, duration, timeZone) {
|
|
105
|
-
const normalizedDate =
|
|
105
|
+
const normalizedDate = this.normalizeDate(date);
|
|
106
106
|
const effectiveTimeZone = timeZone || this.TIMEZONE;
|
|
107
107
|
return dateFns.add(new tz.TZDate(normalizedDate, effectiveTimeZone), duration);
|
|
108
108
|
}
|
|
@@ -122,6 +122,9 @@ class DateUtil {
|
|
|
122
122
|
static fromMillis(milliseconds) {
|
|
123
123
|
return new Date(milliseconds);
|
|
124
124
|
}
|
|
125
|
+
static normalizeDate(date) {
|
|
126
|
+
return typeof date === 'number' ? this.fromMillis(date) : date;
|
|
127
|
+
}
|
|
125
128
|
/**
|
|
126
129
|
* Converts a Date object to a timestamp (in milliseconds).
|
|
127
130
|
* @param date The Date object to convert.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateUtil.cjs","sources":["../../../../src/utils/date/DateUtil.ts"],"sourcesContent":["import { TZDate } from '@date-fns/tz';\nimport { add, compareAsc, differenceInCalendarDays, differenceInCalendarMonths, differenceInCalendarYears, differenceInHours, differenceInSeconds, Duration, endOfDay, format, isLeapYear, isValid, parse, startOfDay } from 'date-fns';\nimport { IllegalArgumentException } from '../../exceptions';\n\n/**\n * Utility class for date and time operations. Provides methods for parsing,\n * formatting, and performing calculations with dates and times.\n */\nexport class DateUtil {\n\n static readonly ISO_8601_FORMAT = \"yyyy-MM-dd'T'HH:mm:ss.SSSxxx\"\n static readonly TIMEZONE = \"UTC\"\n\n /**\n * Gets the current date and time in the specified time zone.\n * @param timeZone The IANA time zone identifier.\n * @returns Current date and time in the specified time zone.\n */\n static now(timeZone: string): Date {\n return new TZDate(new Date(), timeZone);\n }\n\n /**\n * Gets the current time in milliseconds since the Unix epoch.\n * @returns Current time in milliseconds.\n */\n static nowInMillis(): number {\n return Date.now();\n }\n\n /**\n * Parses a date string into a Date object.\n * @param dateString The date string to parse.\n * @param dateFormat The format of the date string (default: ISO_8601_FORMAT).\n * @param timeZone The IANA time zone identifier.\n * @throws {IllegalArgumentException} If the date string is invalid.\n * @returns Parsed Date object.\n */\n static readDate(dateString: string, dateFormat = this.ISO_8601_FORMAT, timeZone: string): Date {\n const date = parse(dateString, dateFormat, TZDate.tz(timeZone));\n if (!isValid(date)) {\n throw new IllegalArgumentException('Invalid date string or date format');\n }\n return date;\n }\n\n /**\n * Formats a Date or timestamp into a string.\n * @param date The date or timestamp to format.\n * @param timeZone The IANA time zone identifier.\n * @param dateFormat The desired output format (default: ISO_8601_FORMAT).\n * @returns Formatted date string.\n */\n static printDate(date: Date, timeZone: string, dateFormat?: string): string;\n static printDate(date: number, timeZone: string, dateFormat?: string): string;\n static printDate(date: Date | number, timeZone: string, dateFormat: string = this.ISO_8601_FORMAT): string {\n const normalizedDate = typeof date === 'number' ? DateUtil.fromMillis(date) : date;\n return format(new TZDate(normalizedDate, timeZone), dateFormat);\n }\n\n /**\n * Gets the start of the day for a given date or timestamp.\n * @param date The date or timestamp to calculate from.\n * @param timeZone The IANA time zone identifier.\n * @returns The start of the day as a Date object.\n */\n static getStartOfDay(date: Date, timeZone: string): Date;\n static getStartOfDay(date: number, timeZone: string): Date;\n static getStartOfDay(date: Date | number, timeZone: string): Date {\n const normalizedDate = typeof date === 'number' ? DateUtil.fromMillis(date) : date;\n return startOfDay(new TZDate(normalizedDate, timeZone));\n }\n\n /**\n * Gets the end of the day for a given date or timestamp.\n * @param date The date or timestamp to calculate from.\n * @param timeZone The IANA time zone identifier.\n * @returns The end of the day as a Date object.\n */\n static getEndOfDay(date: Date, timeZone: string): Date;\n static getEndOfDay(date: number, timeZone: string): Date;\n static getEndOfDay(date: Date | number, timeZone: string): Date {\n const normalizedDate = typeof date === 'number' ? DateUtil.fromMillis(date) : date;\n return endOfDay(new TZDate(normalizedDate, timeZone));\n }\n\n /**\n * Checks if a date string is valid according to the specified format.\n * @param dateString The date string to validate.\n * @param dateFormat Optional date format (default: ISO_8601_FORMAT).\n * @returns True if the date is valid, false otherwise.\n */\n static isValidDate(dateString: string, dateFormat?: string): boolean {\n try {\n DateUtil.readDate(dateString, dateFormat, \"UTC\");\n return true;\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Calculates the absolute number of calendar days between two dates or timestamps.\n * Since day boundaries depend on a calendar, callers can optionally provide a time zone\n * so the same pair of instants is interpreted consistently across machines.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @param timeZone Optional IANA time zone identifier used for calendar comparisons.\n * @returns Number of days between the two dates.\n */\n static daysInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number;\n static daysInBetween(firstDate: number, secondDate: number, timeZone?: string): number;\n static daysInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number {\n const first = typeof firstDate === 'number' ? DateUtil.fromMillis(firstDate) : firstDate;\n const second = typeof secondDate === 'number' ? DateUtil.fromMillis(secondDate) : secondDate;\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return Math.abs(\n differenceInCalendarDays(\n new TZDate(first, effectiveTimeZone),\n new TZDate(second, effectiveTimeZone),\n )\n );\n }\n\n /**\n * Calculates the absolute number of calendar months between two dates or timestamps.\n * Since month boundaries depend on a calendar, callers can optionally provide a time zone\n * so the same pair of instants is interpreted consistently across machines.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @param timeZone Optional IANA time zone identifier used for calendar comparisons.\n * @returns The number of months between the two dates.\n */\n static monthsInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number;\n static monthsInBetween(firstDate: number, secondDate: number, timeZone?: string): number;\n static monthsInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number {\n const first = typeof firstDate === 'number' ? DateUtil.fromMillis(firstDate) : firstDate;\n const second = typeof secondDate === 'number' ? DateUtil.fromMillis(secondDate) : secondDate;\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return Math.abs(\n differenceInCalendarMonths(\n new TZDate(first, effectiveTimeZone),\n new TZDate(second, effectiveTimeZone),\n )\n );\n }\n\n /**\n * Calculates the absolute number of calendar years between two dates or timestamps.\n * Since year boundaries depend on a calendar, callers can optionally provide a time zone\n * so the same pair of instants is interpreted consistently across machines.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @param timeZone Optional IANA time zone identifier used for calendar comparisons.\n * @returns The number of years between the two dates.\n */\n static yearsInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number;\n static yearsInBetween(firstDate: number, secondDate: number, timeZone?: string): number;\n static yearsInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number {\n const first = typeof firstDate === 'number' ? DateUtil.fromMillis(firstDate) : firstDate;\n const second = typeof secondDate === 'number' ? DateUtil.fromMillis(secondDate) : secondDate;\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return Math.abs(\n differenceInCalendarYears(\n new TZDate(first, effectiveTimeZone),\n new TZDate(second, effectiveTimeZone),\n )\n );\n }\n\n /**\n * Calculates the absolute elapsed number of hours between two dates or timestamps.\n * This is duration-based, not calendar-based, so it is independent of time zone.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @returns The number of hours between the two dates.\n */\n static hoursInBetween(firstDate: Date, secondDate: Date): number;\n static hoursInBetween(firstDate: number, secondDate: number): number;\n static hoursInBetween(firstDate: Date | number, secondDate: Date | number): number {\n const first = typeof firstDate === 'number' ? DateUtil.fromMillis(firstDate) : firstDate;\n const second = typeof secondDate === 'number' ? DateUtil.fromMillis(secondDate) : secondDate;\n return Math.abs(differenceInHours(first, second));\n }\n\n /**\n * Calculates the absolute elapsed number of seconds between two dates or timestamps.\n * This is duration-based, not calendar-based, so it is independent of time zone.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @returns The number of seconds between the two dates.\n */\n static secondsInBetween(firstDate: Date, secondDate: Date): number;\n static secondsInBetween(firstDate: number, secondDate: number): number;\n static secondsInBetween(firstDate: Date | number, secondDate: Date | number): number {\n const first = typeof firstDate === 'number' ? DateUtil.fromMillis(firstDate) : firstDate;\n const second = typeof secondDate === 'number' ? DateUtil.fromMillis(secondDate) : secondDate;\n return Math.abs(differenceInSeconds(first, second));\n }\n\n /**\n * Compares two dates or timestamps.\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @returns `-1` if the first date is earlier, `1` if it is later, or `0` if the two dates are equal.\n */\n static compareDates(firstDate: Date, secondDate: Date): -1 | 0 | 1;\n static compareDates(firstDate: number, secondDate: number): -1 | 0 | 1;\n static compareDates(firstDate: Date | number, secondDate: Date | number): -1 | 0 | 1 {\n const first = typeof firstDate === 'number' ? DateUtil.fromMillis(firstDate) : firstDate;\n const second = typeof secondDate === 'number' ? DateUtil.fromMillis(secondDate) : secondDate;\n\n return compareAsc(first, second) as -1 | 0 | 1;\n }\n\n /**\n * Adds a duration (e.g., days, months, years) to a given date or timestamp.\n * When a time zone is provided, the duration is applied using calendar arithmetic\n * in that time zone so month-end or day-boundary business rules stay aligned locally.\n *\n * @param date The base date or timestamp to which the duration will be added.\n * @param duration An object specifying the duration (e.g., `{ days: 1, months: 2 }`).\n * @param timeZone Optional IANA time zone identifier used for calendar math.\n * @returns A new Date object with the duration added.\n */\n static addDuration(date: Date, duration: Duration, timeZone?: string): Date;\n static addDuration(date: number, duration: Duration, timeZone?: string): Date;\n static addDuration(date: Date | number, duration: Duration, timeZone?: string): Date {\n const normalizedDate = typeof date === 'number' ? DateUtil.fromMillis(date) : date;\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return add(new TZDate(normalizedDate, effectiveTimeZone), duration);\n }\n\n /**\n * Determines whether a given year is a leap year.\n * @param year The year to check.\n * @returns `true` if the year is a leap year, otherwise `false`.\n */\n static isLeapYear(year: number): boolean {\n return isLeapYear(DateUtil.readDate(year.toString(), 'yyyy', \"UTC\"));\n }\n\n\n /**\n * Converts a timestamp (in milliseconds) to a Date object.\n * @param milliseconds The timestamp in milliseconds since the Unix epoch.\n * @returns A Date object representing the provided timestamp.\n */\n static fromMillis(milliseconds: number): Date {\n return new Date(milliseconds);\n }\n\n /**\n * Converts a Date object to a timestamp (in milliseconds).\n * @param date The Date object to convert.\n * @returns The timestamp in milliseconds since the Unix epoch.\n */\n static toMillis(date: Date): number {\n return date.getTime();\n }\n}\n"],"names":["TZDate","parse","isValid","IllegalArgumentException","format","startOfDay","endOfDay","differenceInCalendarDays","differenceInCalendarMonths","differenceInCalendarYears","differenceInHours","differenceInSeconds","compareAsc","add","isLeapYear"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DateUtil.cjs","sources":["../../../../src/utils/date/DateUtil.ts"],"sourcesContent":["import { TZDate } from '@date-fns/tz';\nimport { add, compareAsc, differenceInCalendarDays, differenceInCalendarMonths, differenceInCalendarYears, differenceInHours, differenceInSeconds, Duration, endOfDay, format, isLeapYear, isValid, parse, startOfDay } from 'date-fns';\nimport { IllegalArgumentException } from '../../exceptions';\n\n/**\n * Utility class for date and time operations. Provides methods for parsing,\n * formatting, and performing calculations with dates and times.\n */\nexport class DateUtil {\n\n static readonly ISO_8601_FORMAT = \"yyyy-MM-dd'T'HH:mm:ss.SSSxxx\"\n static readonly TIMEZONE = \"UTC\"\n\n /**\n * Gets the current date and time in the specified time zone.\n * @param timeZone The IANA time zone identifier.\n * @returns Current date and time in the specified time zone.\n */\n static now(timeZone: string): Date {\n return new TZDate(new Date(), timeZone);\n }\n\n /**\n * Gets the current time in milliseconds since the Unix epoch.\n * @returns Current time in milliseconds.\n */\n static nowInMillis(): number {\n return Date.now();\n }\n\n /**\n * Parses a date string into a Date object.\n * @param dateString The date string to parse.\n * @param dateFormat The format of the date string (default: ISO_8601_FORMAT).\n * @param timeZone The IANA time zone identifier.\n * @throws {IllegalArgumentException} If the date string is invalid.\n * @returns Parsed Date object.\n */\n static readDate(dateString: string, dateFormat = this.ISO_8601_FORMAT, timeZone: string): Date {\n const date = parse(dateString, dateFormat, TZDate.tz(timeZone));\n if (!isValid(date)) {\n throw new IllegalArgumentException('Invalid date string or date format');\n }\n return date;\n }\n\n /**\n * Formats a Date or timestamp into a string.\n * @param date The date or timestamp to format.\n * @param timeZone The IANA time zone identifier.\n * @param dateFormat The desired output format (default: ISO_8601_FORMAT).\n * @returns Formatted date string.\n */\n static printDate(date: Date, timeZone: string, dateFormat?: string): string;\n static printDate(date: number, timeZone: string, dateFormat?: string): string;\n static printDate(date: Date | number, timeZone: string, dateFormat: string = this.ISO_8601_FORMAT): string {\n const normalizedDate = this.normalizeDate(date);\n return format(new TZDate(normalizedDate, timeZone), dateFormat);\n }\n\n /**\n * Gets the start of the day for a given date or timestamp.\n * @param date The date or timestamp to calculate from.\n * @param timeZone The IANA time zone identifier.\n * @returns The start of the day as a Date object.\n */\n static getStartOfDay(date: Date, timeZone: string): Date;\n static getStartOfDay(date: number, timeZone: string): Date;\n static getStartOfDay(date: Date | number, timeZone: string): Date {\n const normalizedDate = this.normalizeDate(date);\n return startOfDay(new TZDate(normalizedDate, timeZone));\n }\n\n /**\n * Gets the end of the day for a given date or timestamp.\n * @param date The date or timestamp to calculate from.\n * @param timeZone The IANA time zone identifier.\n * @returns The end of the day as a Date object.\n */\n static getEndOfDay(date: Date, timeZone: string): Date;\n static getEndOfDay(date: number, timeZone: string): Date;\n static getEndOfDay(date: Date | number, timeZone: string): Date {\n const normalizedDate = this.normalizeDate(date);\n return endOfDay(new TZDate(normalizedDate, timeZone));\n }\n\n /**\n * Checks if a date string is valid according to the specified format.\n * @param dateString The date string to validate.\n * @param dateFormat Optional date format (default: ISO_8601_FORMAT).\n * @returns True if the date is valid, false otherwise.\n */\n static isValidDate(dateString: string, dateFormat?: string): boolean {\n try {\n DateUtil.readDate(dateString, dateFormat, \"UTC\");\n return true;\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Calculates the absolute number of calendar days between two dates or timestamps.\n * Since day boundaries depend on a calendar, callers can optionally provide a time zone\n * so the same pair of instants is interpreted consistently across machines.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @param timeZone Optional IANA time zone identifier used for calendar comparisons.\n * @returns Number of days between the two dates.\n */\n static daysInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number;\n static daysInBetween(firstDate: number, secondDate: number, timeZone?: string): number;\n static daysInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number {\n const first = this.normalizeDate(firstDate);\n const second = this.normalizeDate(secondDate);\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return Math.abs(\n differenceInCalendarDays(\n new TZDate(first, effectiveTimeZone),\n new TZDate(second, effectiveTimeZone),\n )\n );\n }\n\n /**\n * Calculates the absolute number of calendar months between two dates or timestamps.\n * Since month boundaries depend on a calendar, callers can optionally provide a time zone\n * so the same pair of instants is interpreted consistently across machines.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @param timeZone Optional IANA time zone identifier used for calendar comparisons.\n * @returns The number of months between the two dates.\n */\n static monthsInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number;\n static monthsInBetween(firstDate: number, secondDate: number, timeZone?: string): number;\n static monthsInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number {\n const first = this.normalizeDate(firstDate);\n const second = this.normalizeDate(secondDate);\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return Math.abs(\n differenceInCalendarMonths(\n new TZDate(first, effectiveTimeZone),\n new TZDate(second, effectiveTimeZone),\n )\n );\n }\n\n /**\n * Calculates the absolute number of calendar years between two dates or timestamps.\n * Since year boundaries depend on a calendar, callers can optionally provide a time zone\n * so the same pair of instants is interpreted consistently across machines.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @param timeZone Optional IANA time zone identifier used for calendar comparisons.\n * @returns The number of years between the two dates.\n */\n static yearsInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number;\n static yearsInBetween(firstDate: number, secondDate: number, timeZone?: string): number;\n static yearsInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number {\n const first = this.normalizeDate(firstDate);\n const second = this.normalizeDate(secondDate);\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return Math.abs(\n differenceInCalendarYears(\n new TZDate(first, effectiveTimeZone),\n new TZDate(second, effectiveTimeZone),\n )\n );\n }\n\n /**\n * Calculates the absolute elapsed number of hours between two dates or timestamps.\n * This is duration-based, not calendar-based, so it is independent of time zone.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @returns The number of hours between the two dates.\n */\n static hoursInBetween(firstDate: Date, secondDate: Date): number;\n static hoursInBetween(firstDate: number, secondDate: number): number;\n static hoursInBetween(firstDate: Date | number, secondDate: Date | number): number {\n const first = this.normalizeDate(firstDate);\n const second = this.normalizeDate(secondDate);\n return Math.abs(differenceInHours(first, second));\n }\n\n /**\n * Calculates the absolute elapsed number of seconds between two dates or timestamps.\n * This is duration-based, not calendar-based, so it is independent of time zone.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @returns The number of seconds between the two dates.\n */\n static secondsInBetween(firstDate: Date, secondDate: Date): number;\n static secondsInBetween(firstDate: number, secondDate: number): number;\n static secondsInBetween(firstDate: Date | number, secondDate: Date | number): number {\n const first = this.normalizeDate(firstDate);\n const second = this.normalizeDate(secondDate);\n return Math.abs(differenceInSeconds(first, second));\n }\n\n /**\n * Compares two dates or timestamps.\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @returns `-1` if the first date is earlier, `1` if it is later, or `0` if the two dates are equal.\n */\n static compareDates(firstDate: Date, secondDate: Date): -1 | 0 | 1;\n static compareDates(firstDate: number, secondDate: number): -1 | 0 | 1;\n static compareDates(firstDate: Date | number, secondDate: Date | number): -1 | 0 | 1 {\n const first = this.normalizeDate(firstDate);\n const second = this.normalizeDate(secondDate);\n\n return compareAsc(first, second) as -1 | 0 | 1;\n }\n\n /**\n * Adds a duration (e.g., days, months, years) to a given date or timestamp.\n * When a time zone is provided, the duration is applied using calendar arithmetic\n * in that time zone so month-end or day-boundary business rules stay aligned locally.\n *\n * @param date The base date or timestamp to which the duration will be added.\n * @param duration An object specifying the duration (e.g., `{ days: 1, months: 2 }`).\n * @param timeZone Optional IANA time zone identifier used for calendar math.\n * @returns A new Date object with the duration added.\n */\n static addDuration(date: Date, duration: Duration, timeZone?: string): Date;\n static addDuration(date: number, duration: Duration, timeZone?: string): Date;\n static addDuration(date: Date | number, duration: Duration, timeZone?: string): Date {\n const normalizedDate = this.normalizeDate(date);\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return add(new TZDate(normalizedDate, effectiveTimeZone), duration);\n }\n\n /**\n * Determines whether a given year is a leap year.\n * @param year The year to check.\n * @returns `true` if the year is a leap year, otherwise `false`.\n */\n static isLeapYear(year: number): boolean {\n return isLeapYear(DateUtil.readDate(year.toString(), 'yyyy', \"UTC\"));\n }\n\n\n /**\n * Converts a timestamp (in milliseconds) to a Date object.\n * @param milliseconds The timestamp in milliseconds since the Unix epoch.\n * @returns A Date object representing the provided timestamp.\n */\n static fromMillis(milliseconds: number): Date {\n return new Date(milliseconds);\n }\n\n protected static normalizeDate(date: Date | number): Date {\n return typeof date === 'number' ? this.fromMillis(date) : date;\n }\n\n /**\n * Converts a Date object to a timestamp (in milliseconds).\n * @param date The Date object to convert.\n * @returns The timestamp in milliseconds since the Unix epoch.\n */\n static toMillis(date: Date): number {\n return date.getTime();\n }\n}\n"],"names":["TZDate","parse","isValid","IllegalArgumentException","format","startOfDay","endOfDay","differenceInCalendarDays","differenceInCalendarMonths","differenceInCalendarYears","differenceInHours","differenceInSeconds","compareAsc","add","isLeapYear"],"mappings":"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"}
|
|
@@ -40,15 +40,15 @@ class DateUtil {
|
|
|
40
40
|
return date;
|
|
41
41
|
}
|
|
42
42
|
static printDate(date, timeZone, dateFormat = this.ISO_8601_FORMAT) {
|
|
43
|
-
const normalizedDate =
|
|
43
|
+
const normalizedDate = this.normalizeDate(date);
|
|
44
44
|
return format(new TZDate(normalizedDate, timeZone), dateFormat);
|
|
45
45
|
}
|
|
46
46
|
static getStartOfDay(date, timeZone) {
|
|
47
|
-
const normalizedDate =
|
|
47
|
+
const normalizedDate = this.normalizeDate(date);
|
|
48
48
|
return startOfDay(new TZDate(normalizedDate, timeZone));
|
|
49
49
|
}
|
|
50
50
|
static getEndOfDay(date, timeZone) {
|
|
51
|
-
const normalizedDate =
|
|
51
|
+
const normalizedDate = this.normalizeDate(date);
|
|
52
52
|
return endOfDay(new TZDate(normalizedDate, timeZone));
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
@@ -67,40 +67,40 @@ class DateUtil {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
static daysInBetween(firstDate, secondDate, timeZone) {
|
|
70
|
-
const first =
|
|
71
|
-
const second =
|
|
70
|
+
const first = this.normalizeDate(firstDate);
|
|
71
|
+
const second = this.normalizeDate(secondDate);
|
|
72
72
|
const effectiveTimeZone = timeZone || this.TIMEZONE;
|
|
73
73
|
return Math.abs(differenceInCalendarDays(new TZDate(first, effectiveTimeZone), new TZDate(second, effectiveTimeZone)));
|
|
74
74
|
}
|
|
75
75
|
static monthsInBetween(firstDate, secondDate, timeZone) {
|
|
76
|
-
const first =
|
|
77
|
-
const second =
|
|
76
|
+
const first = this.normalizeDate(firstDate);
|
|
77
|
+
const second = this.normalizeDate(secondDate);
|
|
78
78
|
const effectiveTimeZone = timeZone || this.TIMEZONE;
|
|
79
79
|
return Math.abs(differenceInCalendarMonths(new TZDate(first, effectiveTimeZone), new TZDate(second, effectiveTimeZone)));
|
|
80
80
|
}
|
|
81
81
|
static yearsInBetween(firstDate, secondDate, timeZone) {
|
|
82
|
-
const first =
|
|
83
|
-
const second =
|
|
82
|
+
const first = this.normalizeDate(firstDate);
|
|
83
|
+
const second = this.normalizeDate(secondDate);
|
|
84
84
|
const effectiveTimeZone = timeZone || this.TIMEZONE;
|
|
85
85
|
return Math.abs(differenceInCalendarYears(new TZDate(first, effectiveTimeZone), new TZDate(second, effectiveTimeZone)));
|
|
86
86
|
}
|
|
87
87
|
static hoursInBetween(firstDate, secondDate) {
|
|
88
|
-
const first =
|
|
89
|
-
const second =
|
|
88
|
+
const first = this.normalizeDate(firstDate);
|
|
89
|
+
const second = this.normalizeDate(secondDate);
|
|
90
90
|
return Math.abs(differenceInHours(first, second));
|
|
91
91
|
}
|
|
92
92
|
static secondsInBetween(firstDate, secondDate) {
|
|
93
|
-
const first =
|
|
94
|
-
const second =
|
|
93
|
+
const first = this.normalizeDate(firstDate);
|
|
94
|
+
const second = this.normalizeDate(secondDate);
|
|
95
95
|
return Math.abs(differenceInSeconds(first, second));
|
|
96
96
|
}
|
|
97
97
|
static compareDates(firstDate, secondDate) {
|
|
98
|
-
const first =
|
|
99
|
-
const second =
|
|
98
|
+
const first = this.normalizeDate(firstDate);
|
|
99
|
+
const second = this.normalizeDate(secondDate);
|
|
100
100
|
return compareAsc(first, second);
|
|
101
101
|
}
|
|
102
102
|
static addDuration(date, duration, timeZone) {
|
|
103
|
-
const normalizedDate =
|
|
103
|
+
const normalizedDate = this.normalizeDate(date);
|
|
104
104
|
const effectiveTimeZone = timeZone || this.TIMEZONE;
|
|
105
105
|
return add(new TZDate(normalizedDate, effectiveTimeZone), duration);
|
|
106
106
|
}
|
|
@@ -120,6 +120,9 @@ class DateUtil {
|
|
|
120
120
|
static fromMillis(milliseconds) {
|
|
121
121
|
return new Date(milliseconds);
|
|
122
122
|
}
|
|
123
|
+
static normalizeDate(date) {
|
|
124
|
+
return typeof date === 'number' ? this.fromMillis(date) : date;
|
|
125
|
+
}
|
|
123
126
|
/**
|
|
124
127
|
* Converts a Date object to a timestamp (in milliseconds).
|
|
125
128
|
* @param date The Date object to convert.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateUtil.js","sources":["../../../../src/utils/date/DateUtil.ts"],"sourcesContent":["import { TZDate } from '@date-fns/tz';\nimport { add, compareAsc, differenceInCalendarDays, differenceInCalendarMonths, differenceInCalendarYears, differenceInHours, differenceInSeconds, Duration, endOfDay, format, isLeapYear, isValid, parse, startOfDay } from 'date-fns';\nimport { IllegalArgumentException } from '../../exceptions';\n\n/**\n * Utility class for date and time operations. Provides methods for parsing,\n * formatting, and performing calculations with dates and times.\n */\nexport class DateUtil {\n\n static readonly ISO_8601_FORMAT = \"yyyy-MM-dd'T'HH:mm:ss.SSSxxx\"\n static readonly TIMEZONE = \"UTC\"\n\n /**\n * Gets the current date and time in the specified time zone.\n * @param timeZone The IANA time zone identifier.\n * @returns Current date and time in the specified time zone.\n */\n static now(timeZone: string): Date {\n return new TZDate(new Date(), timeZone);\n }\n\n /**\n * Gets the current time in milliseconds since the Unix epoch.\n * @returns Current time in milliseconds.\n */\n static nowInMillis(): number {\n return Date.now();\n }\n\n /**\n * Parses a date string into a Date object.\n * @param dateString The date string to parse.\n * @param dateFormat The format of the date string (default: ISO_8601_FORMAT).\n * @param timeZone The IANA time zone identifier.\n * @throws {IllegalArgumentException} If the date string is invalid.\n * @returns Parsed Date object.\n */\n static readDate(dateString: string, dateFormat = this.ISO_8601_FORMAT, timeZone: string): Date {\n const date = parse(dateString, dateFormat, TZDate.tz(timeZone));\n if (!isValid(date)) {\n throw new IllegalArgumentException('Invalid date string or date format');\n }\n return date;\n }\n\n /**\n * Formats a Date or timestamp into a string.\n * @param date The date or timestamp to format.\n * @param timeZone The IANA time zone identifier.\n * @param dateFormat The desired output format (default: ISO_8601_FORMAT).\n * @returns Formatted date string.\n */\n static printDate(date: Date, timeZone: string, dateFormat?: string): string;\n static printDate(date: number, timeZone: string, dateFormat?: string): string;\n static printDate(date: Date | number, timeZone: string, dateFormat: string = this.ISO_8601_FORMAT): string {\n const normalizedDate = typeof date === 'number' ? DateUtil.fromMillis(date) : date;\n return format(new TZDate(normalizedDate, timeZone), dateFormat);\n }\n\n /**\n * Gets the start of the day for a given date or timestamp.\n * @param date The date or timestamp to calculate from.\n * @param timeZone The IANA time zone identifier.\n * @returns The start of the day as a Date object.\n */\n static getStartOfDay(date: Date, timeZone: string): Date;\n static getStartOfDay(date: number, timeZone: string): Date;\n static getStartOfDay(date: Date | number, timeZone: string): Date {\n const normalizedDate = typeof date === 'number' ? DateUtil.fromMillis(date) : date;\n return startOfDay(new TZDate(normalizedDate, timeZone));\n }\n\n /**\n * Gets the end of the day for a given date or timestamp.\n * @param date The date or timestamp to calculate from.\n * @param timeZone The IANA time zone identifier.\n * @returns The end of the day as a Date object.\n */\n static getEndOfDay(date: Date, timeZone: string): Date;\n static getEndOfDay(date: number, timeZone: string): Date;\n static getEndOfDay(date: Date | number, timeZone: string): Date {\n const normalizedDate = typeof date === 'number' ? DateUtil.fromMillis(date) : date;\n return endOfDay(new TZDate(normalizedDate, timeZone));\n }\n\n /**\n * Checks if a date string is valid according to the specified format.\n * @param dateString The date string to validate.\n * @param dateFormat Optional date format (default: ISO_8601_FORMAT).\n * @returns True if the date is valid, false otherwise.\n */\n static isValidDate(dateString: string, dateFormat?: string): boolean {\n try {\n DateUtil.readDate(dateString, dateFormat, \"UTC\");\n return true;\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Calculates the absolute number of calendar days between two dates or timestamps.\n * Since day boundaries depend on a calendar, callers can optionally provide a time zone\n * so the same pair of instants is interpreted consistently across machines.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @param timeZone Optional IANA time zone identifier used for calendar comparisons.\n * @returns Number of days between the two dates.\n */\n static daysInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number;\n static daysInBetween(firstDate: number, secondDate: number, timeZone?: string): number;\n static daysInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number {\n const first = typeof firstDate === 'number' ? DateUtil.fromMillis(firstDate) : firstDate;\n const second = typeof secondDate === 'number' ? DateUtil.fromMillis(secondDate) : secondDate;\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return Math.abs(\n differenceInCalendarDays(\n new TZDate(first, effectiveTimeZone),\n new TZDate(second, effectiveTimeZone),\n )\n );\n }\n\n /**\n * Calculates the absolute number of calendar months between two dates or timestamps.\n * Since month boundaries depend on a calendar, callers can optionally provide a time zone\n * so the same pair of instants is interpreted consistently across machines.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @param timeZone Optional IANA time zone identifier used for calendar comparisons.\n * @returns The number of months between the two dates.\n */\n static monthsInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number;\n static monthsInBetween(firstDate: number, secondDate: number, timeZone?: string): number;\n static monthsInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number {\n const first = typeof firstDate === 'number' ? DateUtil.fromMillis(firstDate) : firstDate;\n const second = typeof secondDate === 'number' ? DateUtil.fromMillis(secondDate) : secondDate;\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return Math.abs(\n differenceInCalendarMonths(\n new TZDate(first, effectiveTimeZone),\n new TZDate(second, effectiveTimeZone),\n )\n );\n }\n\n /**\n * Calculates the absolute number of calendar years between two dates or timestamps.\n * Since year boundaries depend on a calendar, callers can optionally provide a time zone\n * so the same pair of instants is interpreted consistently across machines.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @param timeZone Optional IANA time zone identifier used for calendar comparisons.\n * @returns The number of years between the two dates.\n */\n static yearsInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number;\n static yearsInBetween(firstDate: number, secondDate: number, timeZone?: string): number;\n static yearsInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number {\n const first = typeof firstDate === 'number' ? DateUtil.fromMillis(firstDate) : firstDate;\n const second = typeof secondDate === 'number' ? DateUtil.fromMillis(secondDate) : secondDate;\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return Math.abs(\n differenceInCalendarYears(\n new TZDate(first, effectiveTimeZone),\n new TZDate(second, effectiveTimeZone),\n )\n );\n }\n\n /**\n * Calculates the absolute elapsed number of hours between two dates or timestamps.\n * This is duration-based, not calendar-based, so it is independent of time zone.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @returns The number of hours between the two dates.\n */\n static hoursInBetween(firstDate: Date, secondDate: Date): number;\n static hoursInBetween(firstDate: number, secondDate: number): number;\n static hoursInBetween(firstDate: Date | number, secondDate: Date | number): number {\n const first = typeof firstDate === 'number' ? DateUtil.fromMillis(firstDate) : firstDate;\n const second = typeof secondDate === 'number' ? DateUtil.fromMillis(secondDate) : secondDate;\n return Math.abs(differenceInHours(first, second));\n }\n\n /**\n * Calculates the absolute elapsed number of seconds between two dates or timestamps.\n * This is duration-based, not calendar-based, so it is independent of time zone.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @returns The number of seconds between the two dates.\n */\n static secondsInBetween(firstDate: Date, secondDate: Date): number;\n static secondsInBetween(firstDate: number, secondDate: number): number;\n static secondsInBetween(firstDate: Date | number, secondDate: Date | number): number {\n const first = typeof firstDate === 'number' ? DateUtil.fromMillis(firstDate) : firstDate;\n const second = typeof secondDate === 'number' ? DateUtil.fromMillis(secondDate) : secondDate;\n return Math.abs(differenceInSeconds(first, second));\n }\n\n /**\n * Compares two dates or timestamps.\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @returns `-1` if the first date is earlier, `1` if it is later, or `0` if the two dates are equal.\n */\n static compareDates(firstDate: Date, secondDate: Date): -1 | 0 | 1;\n static compareDates(firstDate: number, secondDate: number): -1 | 0 | 1;\n static compareDates(firstDate: Date | number, secondDate: Date | number): -1 | 0 | 1 {\n const first = typeof firstDate === 'number' ? DateUtil.fromMillis(firstDate) : firstDate;\n const second = typeof secondDate === 'number' ? DateUtil.fromMillis(secondDate) : secondDate;\n\n return compareAsc(first, second) as -1 | 0 | 1;\n }\n\n /**\n * Adds a duration (e.g., days, months, years) to a given date or timestamp.\n * When a time zone is provided, the duration is applied using calendar arithmetic\n * in that time zone so month-end or day-boundary business rules stay aligned locally.\n *\n * @param date The base date or timestamp to which the duration will be added.\n * @param duration An object specifying the duration (e.g., `{ days: 1, months: 2 }`).\n * @param timeZone Optional IANA time zone identifier used for calendar math.\n * @returns A new Date object with the duration added.\n */\n static addDuration(date: Date, duration: Duration, timeZone?: string): Date;\n static addDuration(date: number, duration: Duration, timeZone?: string): Date;\n static addDuration(date: Date | number, duration: Duration, timeZone?: string): Date {\n const normalizedDate = typeof date === 'number' ? DateUtil.fromMillis(date) : date;\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return add(new TZDate(normalizedDate, effectiveTimeZone), duration);\n }\n\n /**\n * Determines whether a given year is a leap year.\n * @param year The year to check.\n * @returns `true` if the year is a leap year, otherwise `false`.\n */\n static isLeapYear(year: number): boolean {\n return isLeapYear(DateUtil.readDate(year.toString(), 'yyyy', \"UTC\"));\n }\n\n\n /**\n * Converts a timestamp (in milliseconds) to a Date object.\n * @param milliseconds The timestamp in milliseconds since the Unix epoch.\n * @returns A Date object representing the provided timestamp.\n */\n static fromMillis(milliseconds: number): Date {\n return new Date(milliseconds);\n }\n\n /**\n * Converts a Date object to a timestamp (in milliseconds).\n * @param date The Date object to convert.\n * @returns The timestamp in milliseconds since the Unix epoch.\n */\n static toMillis(date: Date): number {\n return date.getTime();\n }\n}\n"],"names":[],"mappings":";;;;AAIA;;;AAGG;MACU,QAAQ,CAAA;aAED,IAAA,CAAA,eAAe,GAAG,8BAA8B,CAAA;aAChD,IAAA,CAAA,QAAQ,GAAG,KAAK,CAAA;AAEhC;;;;AAIG;IACH,OAAO,GAAG,CAAC,QAAgB,EAAA;QACvB,OAAO,IAAI,MAAM,CAAC,IAAI,IAAI,EAAE,EAAE,QAAQ,CAAC;IAC3C;AAEA;;;AAGG;AACH,IAAA,OAAO,WAAW,GAAA;AACd,QAAA,OAAO,IAAI,CAAC,GAAG,EAAE;IACrB;AAEA;;;;;;;AAOG;IACH,OAAO,QAAQ,CAAC,UAAkB,EAAE,UAAU,GAAG,IAAI,CAAC,eAAe,EAAE,QAAgB,EAAA;AACnF,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;AAC/D,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AAChB,YAAA,MAAM,IAAI,wBAAwB,CAAC,oCAAoC,CAAC;QAC5E;AACA,QAAA,OAAO,IAAI;IACf;IAWA,OAAO,SAAS,CAAC,IAAmB,EAAE,QAAgB,EAAE,UAAA,GAAqB,IAAI,CAAC,eAAe,EAAA;AAC7F,QAAA,MAAM,cAAc,GAAG,OAAO,IAAI,KAAK,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,IAAI;AAClF,QAAA,OAAO,MAAM,CAAC,IAAI,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC,EAAE,UAAU,CAAC;IACnE;AAUA,IAAA,OAAO,aAAa,CAAC,IAAmB,EAAE,QAAgB,EAAA;AACtD,QAAA,MAAM,cAAc,GAAG,OAAO,IAAI,KAAK,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,IAAI;QAClF,OAAO,UAAU,CAAC,IAAI,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IAC3D;AAUA,IAAA,OAAO,WAAW,CAAC,IAAmB,EAAE,QAAgB,EAAA;AACpD,QAAA,MAAM,cAAc,GAAG,OAAO,IAAI,KAAK,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,IAAI;QAClF,OAAO,QAAQ,CAAC,IAAI,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IACzD;AAEA;;;;;AAKG;AACH,IAAA,OAAO,WAAW,CAAC,UAAkB,EAAE,UAAmB,EAAA;AACtD,QAAA,IAAI;YACA,QAAQ,CAAC,QAAQ,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,CAAC;AAChD,YAAA,OAAO,IAAI;QACf;QAAE,OAAO,KAAK,EAAE;AACZ,YAAA,OAAO,KAAK;QAChB;IACJ;AAcA,IAAA,OAAO,aAAa,CAAC,SAAwB,EAAE,UAAyB,EAAE,QAAiB,EAAA;AACvF,QAAA,MAAM,KAAK,GAAG,OAAO,SAAS,KAAK,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,SAAS;AACxF,QAAA,MAAM,MAAM,GAAG,OAAO,UAAU,KAAK,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,UAAU;AAC5F,QAAA,MAAM,iBAAiB,GAAG,QAAQ,IAAI,IAAI,CAAC,QAAQ;QACnD,OAAO,IAAI,CAAC,GAAG,CACX,wBAAwB,CACpB,IAAI,MAAM,CAAC,KAAK,EAAE,iBAAiB,CAAC,EACpC,IAAI,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CACxC,CACJ;IACL;AAcA,IAAA,OAAO,eAAe,CAAC,SAAwB,EAAE,UAAyB,EAAE,QAAiB,EAAA;AACzF,QAAA,MAAM,KAAK,GAAG,OAAO,SAAS,KAAK,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,SAAS;AACxF,QAAA,MAAM,MAAM,GAAG,OAAO,UAAU,KAAK,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,UAAU;AAC5F,QAAA,MAAM,iBAAiB,GAAG,QAAQ,IAAI,IAAI,CAAC,QAAQ;QACnD,OAAO,IAAI,CAAC,GAAG,CACX,0BAA0B,CACtB,IAAI,MAAM,CAAC,KAAK,EAAE,iBAAiB,CAAC,EACpC,IAAI,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CACxC,CACJ;IACL;AAcA,IAAA,OAAO,cAAc,CAAC,SAAwB,EAAE,UAAyB,EAAE,QAAiB,EAAA;AACxF,QAAA,MAAM,KAAK,GAAG,OAAO,SAAS,KAAK,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,SAAS;AACxF,QAAA,MAAM,MAAM,GAAG,OAAO,UAAU,KAAK,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,UAAU;AAC5F,QAAA,MAAM,iBAAiB,GAAG,QAAQ,IAAI,IAAI,CAAC,QAAQ;QACnD,OAAO,IAAI,CAAC,GAAG,CACX,yBAAyB,CACrB,IAAI,MAAM,CAAC,KAAK,EAAE,iBAAiB,CAAC,EACpC,IAAI,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CACxC,CACJ;IACL;AAYA,IAAA,OAAO,cAAc,CAAC,SAAwB,EAAE,UAAyB,EAAA;AACrE,QAAA,MAAM,KAAK,GAAG,OAAO,SAAS,KAAK,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,SAAS;AACxF,QAAA,MAAM,MAAM,GAAG,OAAO,UAAU,KAAK,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,UAAU;QAC5F,OAAO,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACrD;AAYA,IAAA,OAAO,gBAAgB,CAAC,SAAwB,EAAE,UAAyB,EAAA;AACvE,QAAA,MAAM,KAAK,GAAG,OAAO,SAAS,KAAK,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,SAAS;AACxF,QAAA,MAAM,MAAM,GAAG,OAAO,UAAU,KAAK,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,UAAU;QAC5F,OAAO,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACvD;AAUA,IAAA,OAAO,YAAY,CAAC,SAAwB,EAAE,UAAyB,EAAA;AACnE,QAAA,MAAM,KAAK,GAAG,OAAO,SAAS,KAAK,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,SAAS;AACxF,QAAA,MAAM,MAAM,GAAG,OAAO,UAAU,KAAK,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,UAAU;AAE5F,QAAA,OAAO,UAAU,CAAC,KAAK,EAAE,MAAM,CAAe;IAClD;AAcA,IAAA,OAAO,WAAW,CAAC,IAAmB,EAAE,QAAkB,EAAE,QAAiB,EAAA;AACzE,QAAA,MAAM,cAAc,GAAG,OAAO,IAAI,KAAK,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,IAAI;AAClF,QAAA,MAAM,iBAAiB,GAAG,QAAQ,IAAI,IAAI,CAAC,QAAQ;AACnD,QAAA,OAAO,GAAG,CAAC,IAAI,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,EAAE,QAAQ,CAAC;IACvE;AAEA;;;;AAIG;IACH,OAAO,UAAU,CAAC,IAAY,EAAA;AAC1B,QAAA,OAAO,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IACxE;AAGA;;;;AAIG;IACH,OAAO,UAAU,CAAC,YAAoB,EAAA;AAClC,QAAA,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC;IACjC;AAEA;;;;AAIG;IACH,OAAO,QAAQ,CAAC,IAAU,EAAA;AACtB,QAAA,OAAO,IAAI,CAAC,OAAO,EAAE;IACzB;;;;;"}
|
|
1
|
+
{"version":3,"file":"DateUtil.js","sources":["../../../../src/utils/date/DateUtil.ts"],"sourcesContent":["import { TZDate } from '@date-fns/tz';\nimport { add, compareAsc, differenceInCalendarDays, differenceInCalendarMonths, differenceInCalendarYears, differenceInHours, differenceInSeconds, Duration, endOfDay, format, isLeapYear, isValid, parse, startOfDay } from 'date-fns';\nimport { IllegalArgumentException } from '../../exceptions';\n\n/**\n * Utility class for date and time operations. Provides methods for parsing,\n * formatting, and performing calculations with dates and times.\n */\nexport class DateUtil {\n\n static readonly ISO_8601_FORMAT = \"yyyy-MM-dd'T'HH:mm:ss.SSSxxx\"\n static readonly TIMEZONE = \"UTC\"\n\n /**\n * Gets the current date and time in the specified time zone.\n * @param timeZone The IANA time zone identifier.\n * @returns Current date and time in the specified time zone.\n */\n static now(timeZone: string): Date {\n return new TZDate(new Date(), timeZone);\n }\n\n /**\n * Gets the current time in milliseconds since the Unix epoch.\n * @returns Current time in milliseconds.\n */\n static nowInMillis(): number {\n return Date.now();\n }\n\n /**\n * Parses a date string into a Date object.\n * @param dateString The date string to parse.\n * @param dateFormat The format of the date string (default: ISO_8601_FORMAT).\n * @param timeZone The IANA time zone identifier.\n * @throws {IllegalArgumentException} If the date string is invalid.\n * @returns Parsed Date object.\n */\n static readDate(dateString: string, dateFormat = this.ISO_8601_FORMAT, timeZone: string): Date {\n const date = parse(dateString, dateFormat, TZDate.tz(timeZone));\n if (!isValid(date)) {\n throw new IllegalArgumentException('Invalid date string or date format');\n }\n return date;\n }\n\n /**\n * Formats a Date or timestamp into a string.\n * @param date The date or timestamp to format.\n * @param timeZone The IANA time zone identifier.\n * @param dateFormat The desired output format (default: ISO_8601_FORMAT).\n * @returns Formatted date string.\n */\n static printDate(date: Date, timeZone: string, dateFormat?: string): string;\n static printDate(date: number, timeZone: string, dateFormat?: string): string;\n static printDate(date: Date | number, timeZone: string, dateFormat: string = this.ISO_8601_FORMAT): string {\n const normalizedDate = this.normalizeDate(date);\n return format(new TZDate(normalizedDate, timeZone), dateFormat);\n }\n\n /**\n * Gets the start of the day for a given date or timestamp.\n * @param date The date or timestamp to calculate from.\n * @param timeZone The IANA time zone identifier.\n * @returns The start of the day as a Date object.\n */\n static getStartOfDay(date: Date, timeZone: string): Date;\n static getStartOfDay(date: number, timeZone: string): Date;\n static getStartOfDay(date: Date | number, timeZone: string): Date {\n const normalizedDate = this.normalizeDate(date);\n return startOfDay(new TZDate(normalizedDate, timeZone));\n }\n\n /**\n * Gets the end of the day for a given date or timestamp.\n * @param date The date or timestamp to calculate from.\n * @param timeZone The IANA time zone identifier.\n * @returns The end of the day as a Date object.\n */\n static getEndOfDay(date: Date, timeZone: string): Date;\n static getEndOfDay(date: number, timeZone: string): Date;\n static getEndOfDay(date: Date | number, timeZone: string): Date {\n const normalizedDate = this.normalizeDate(date);\n return endOfDay(new TZDate(normalizedDate, timeZone));\n }\n\n /**\n * Checks if a date string is valid according to the specified format.\n * @param dateString The date string to validate.\n * @param dateFormat Optional date format (default: ISO_8601_FORMAT).\n * @returns True if the date is valid, false otherwise.\n */\n static isValidDate(dateString: string, dateFormat?: string): boolean {\n try {\n DateUtil.readDate(dateString, dateFormat, \"UTC\");\n return true;\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Calculates the absolute number of calendar days between two dates or timestamps.\n * Since day boundaries depend on a calendar, callers can optionally provide a time zone\n * so the same pair of instants is interpreted consistently across machines.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @param timeZone Optional IANA time zone identifier used for calendar comparisons.\n * @returns Number of days between the two dates.\n */\n static daysInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number;\n static daysInBetween(firstDate: number, secondDate: number, timeZone?: string): number;\n static daysInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number {\n const first = this.normalizeDate(firstDate);\n const second = this.normalizeDate(secondDate);\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return Math.abs(\n differenceInCalendarDays(\n new TZDate(first, effectiveTimeZone),\n new TZDate(second, effectiveTimeZone),\n )\n );\n }\n\n /**\n * Calculates the absolute number of calendar months between two dates or timestamps.\n * Since month boundaries depend on a calendar, callers can optionally provide a time zone\n * so the same pair of instants is interpreted consistently across machines.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @param timeZone Optional IANA time zone identifier used for calendar comparisons.\n * @returns The number of months between the two dates.\n */\n static monthsInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number;\n static monthsInBetween(firstDate: number, secondDate: number, timeZone?: string): number;\n static monthsInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number {\n const first = this.normalizeDate(firstDate);\n const second = this.normalizeDate(secondDate);\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return Math.abs(\n differenceInCalendarMonths(\n new TZDate(first, effectiveTimeZone),\n new TZDate(second, effectiveTimeZone),\n )\n );\n }\n\n /**\n * Calculates the absolute number of calendar years between two dates or timestamps.\n * Since year boundaries depend on a calendar, callers can optionally provide a time zone\n * so the same pair of instants is interpreted consistently across machines.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @param timeZone Optional IANA time zone identifier used for calendar comparisons.\n * @returns The number of years between the two dates.\n */\n static yearsInBetween(firstDate: Date, secondDate: Date, timeZone?: string): number;\n static yearsInBetween(firstDate: number, secondDate: number, timeZone?: string): number;\n static yearsInBetween(firstDate: Date | number, secondDate: Date | number, timeZone?: string): number {\n const first = this.normalizeDate(firstDate);\n const second = this.normalizeDate(secondDate);\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return Math.abs(\n differenceInCalendarYears(\n new TZDate(first, effectiveTimeZone),\n new TZDate(second, effectiveTimeZone),\n )\n );\n }\n\n /**\n * Calculates the absolute elapsed number of hours between two dates or timestamps.\n * This is duration-based, not calendar-based, so it is independent of time zone.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @returns The number of hours between the two dates.\n */\n static hoursInBetween(firstDate: Date, secondDate: Date): number;\n static hoursInBetween(firstDate: number, secondDate: number): number;\n static hoursInBetween(firstDate: Date | number, secondDate: Date | number): number {\n const first = this.normalizeDate(firstDate);\n const second = this.normalizeDate(secondDate);\n return Math.abs(differenceInHours(first, second));\n }\n\n /**\n * Calculates the absolute elapsed number of seconds between two dates or timestamps.\n * This is duration-based, not calendar-based, so it is independent of time zone.\n *\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @returns The number of seconds between the two dates.\n */\n static secondsInBetween(firstDate: Date, secondDate: Date): number;\n static secondsInBetween(firstDate: number, secondDate: number): number;\n static secondsInBetween(firstDate: Date | number, secondDate: Date | number): number {\n const first = this.normalizeDate(firstDate);\n const second = this.normalizeDate(secondDate);\n return Math.abs(differenceInSeconds(first, second));\n }\n\n /**\n * Compares two dates or timestamps.\n * @param firstDate The first date or timestamp.\n * @param secondDate The second date or timestamp.\n * @returns `-1` if the first date is earlier, `1` if it is later, or `0` if the two dates are equal.\n */\n static compareDates(firstDate: Date, secondDate: Date): -1 | 0 | 1;\n static compareDates(firstDate: number, secondDate: number): -1 | 0 | 1;\n static compareDates(firstDate: Date | number, secondDate: Date | number): -1 | 0 | 1 {\n const first = this.normalizeDate(firstDate);\n const second = this.normalizeDate(secondDate);\n\n return compareAsc(first, second) as -1 | 0 | 1;\n }\n\n /**\n * Adds a duration (e.g., days, months, years) to a given date or timestamp.\n * When a time zone is provided, the duration is applied using calendar arithmetic\n * in that time zone so month-end or day-boundary business rules stay aligned locally.\n *\n * @param date The base date or timestamp to which the duration will be added.\n * @param duration An object specifying the duration (e.g., `{ days: 1, months: 2 }`).\n * @param timeZone Optional IANA time zone identifier used for calendar math.\n * @returns A new Date object with the duration added.\n */\n static addDuration(date: Date, duration: Duration, timeZone?: string): Date;\n static addDuration(date: number, duration: Duration, timeZone?: string): Date;\n static addDuration(date: Date | number, duration: Duration, timeZone?: string): Date {\n const normalizedDate = this.normalizeDate(date);\n const effectiveTimeZone = timeZone || this.TIMEZONE;\n return add(new TZDate(normalizedDate, effectiveTimeZone), duration);\n }\n\n /**\n * Determines whether a given year is a leap year.\n * @param year The year to check.\n * @returns `true` if the year is a leap year, otherwise `false`.\n */\n static isLeapYear(year: number): boolean {\n return isLeapYear(DateUtil.readDate(year.toString(), 'yyyy', \"UTC\"));\n }\n\n\n /**\n * Converts a timestamp (in milliseconds) to a Date object.\n * @param milliseconds The timestamp in milliseconds since the Unix epoch.\n * @returns A Date object representing the provided timestamp.\n */\n static fromMillis(milliseconds: number): Date {\n return new Date(milliseconds);\n }\n\n protected static normalizeDate(date: Date | number): Date {\n return typeof date === 'number' ? this.fromMillis(date) : date;\n }\n\n /**\n * Converts a Date object to a timestamp (in milliseconds).\n * @param date The Date object to convert.\n * @returns The timestamp in milliseconds since the Unix epoch.\n */\n static toMillis(date: Date): number {\n return date.getTime();\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -147,6 +147,7 @@ declare class DateUtil {
|
|
|
147
147
|
* @returns A Date object representing the provided timestamp.
|
|
148
148
|
*/
|
|
149
149
|
static fromMillis(milliseconds: number): Date;
|
|
150
|
+
protected static normalizeDate(date: Date | number): Date;
|
|
150
151
|
/**
|
|
151
152
|
* Converts a Date object to a timestamp (in milliseconds).
|
|
152
153
|
* @param date The Date object to convert.
|
package/package.json
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@org-quicko/core",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.6",
|
|
4
4
|
"description": "A library in typescript for common entities and utilities across Quicko",
|
|
5
5
|
"author": "Quicko",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/org-quicko/core-js"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/org-quicko/core-js",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/org-quicko/core-js/issues"
|
|
13
|
+
},
|
|
6
14
|
"main": "dist/cjs/build/node/index.cjs",
|
|
7
15
|
"module": "dist/esm/build/node/index.js",
|
|
8
16
|
"browser": "dist/browser/build/browser/index.js",
|