@reliverse/datetime 2.2.7
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/dist/mod.d.ts +169 -0
- package/dist/mod.js +442 -0
- package/package.json +24 -0
package/dist/mod.d.ts
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
export interface FormatOptions {
|
|
2
|
+
locale?: string;
|
|
3
|
+
timeZone?: string;
|
|
4
|
+
dateStyle?: "full" | "long" | "medium" | "short";
|
|
5
|
+
timeStyle?: "full" | "long" | "medium" | "short";
|
|
6
|
+
year?: "numeric" | "2-digit";
|
|
7
|
+
month?: "numeric" | "2-digit" | "long" | "short" | "narrow";
|
|
8
|
+
day?: "numeric" | "2-digit";
|
|
9
|
+
hour?: "numeric" | "2-digit";
|
|
10
|
+
minute?: "numeric" | "2-digit";
|
|
11
|
+
second?: "numeric" | "2-digit";
|
|
12
|
+
hour12?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface Duration {
|
|
15
|
+
years?: number;
|
|
16
|
+
months?: number;
|
|
17
|
+
weeks?: number;
|
|
18
|
+
days?: number;
|
|
19
|
+
hours?: number;
|
|
20
|
+
minutes?: number;
|
|
21
|
+
seconds?: number;
|
|
22
|
+
milliseconds?: number;
|
|
23
|
+
}
|
|
24
|
+
export interface RelativeTimeOptions {
|
|
25
|
+
numeric?: "always" | "auto";
|
|
26
|
+
style?: "long" | "short" | "narrow";
|
|
27
|
+
locale?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Format a date using Intl.DateTimeFormat with custom options
|
|
31
|
+
*/
|
|
32
|
+
export declare function formatDate(date: Date | number | string, options?: FormatOptions): string;
|
|
33
|
+
/**
|
|
34
|
+
* Format date in ISO 8601 format
|
|
35
|
+
*/
|
|
36
|
+
export declare function formatISO(date: Date | number | string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Format date in RFC 2822 format
|
|
39
|
+
*/
|
|
40
|
+
export declare function formatRFC2822(date: Date | number | string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Format date using a custom format string
|
|
43
|
+
* Supports: YYYY, MM, DD, HH, mm, ss, SSS, AM/PM
|
|
44
|
+
*/
|
|
45
|
+
export declare function formatCustom(date: Date | number | string, format: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Parse a date string into a Date object
|
|
48
|
+
*/
|
|
49
|
+
export declare function parseDate(input: string | number | Date): Date;
|
|
50
|
+
/**
|
|
51
|
+
* Parse ISO 8601 date string
|
|
52
|
+
*/
|
|
53
|
+
export declare function parseISO(isoString: string): Date;
|
|
54
|
+
/**
|
|
55
|
+
* Check if a date string is valid
|
|
56
|
+
*/
|
|
57
|
+
export declare function isValidDate(input: string | number | Date): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Convert date to a specific timezone
|
|
60
|
+
*/
|
|
61
|
+
export declare function toTimezone(date: Date | number | string, timeZone: string): Date;
|
|
62
|
+
/**
|
|
63
|
+
* Get timezone offset in minutes
|
|
64
|
+
*/
|
|
65
|
+
export declare function getTimezoneOffset(date: Date | number | string, timeZone: string): number;
|
|
66
|
+
/**
|
|
67
|
+
* List all available timezones
|
|
68
|
+
*/
|
|
69
|
+
export declare function getAvailableTimezones(): string[];
|
|
70
|
+
/**
|
|
71
|
+
* Get relative time string (e.g., "2 hours ago", "in 3 days")
|
|
72
|
+
*/
|
|
73
|
+
export declare function formatRelativeTime(date: Date | number | string, baseDate?: Date | number | string, options?: RelativeTimeOptions): string;
|
|
74
|
+
/**
|
|
75
|
+
* Calculate duration between two dates
|
|
76
|
+
*/
|
|
77
|
+
export declare function getDuration(start: Date | number | string, end: Date | number | string): Duration;
|
|
78
|
+
/**
|
|
79
|
+
* Format duration as a human-readable string
|
|
80
|
+
*/
|
|
81
|
+
export declare function formatDuration(duration: Duration): string;
|
|
82
|
+
/**
|
|
83
|
+
* Add duration to a date
|
|
84
|
+
*/
|
|
85
|
+
export declare function addDuration(date: Date | number | string, duration: Duration): Date;
|
|
86
|
+
/**
|
|
87
|
+
* Subtract duration from a date
|
|
88
|
+
*/
|
|
89
|
+
export declare function subtractDuration(date: Date | number | string, duration: Duration): Date;
|
|
90
|
+
/**
|
|
91
|
+
* Get start of day
|
|
92
|
+
*/
|
|
93
|
+
export declare function startOfDay(date: Date | number | string): Date;
|
|
94
|
+
/**
|
|
95
|
+
* Get end of day
|
|
96
|
+
*/
|
|
97
|
+
export declare function endOfDay(date: Date | number | string): Date;
|
|
98
|
+
/**
|
|
99
|
+
* Get start of week
|
|
100
|
+
*/
|
|
101
|
+
export declare function startOfWeek(date: Date | number | string, weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6): Date;
|
|
102
|
+
/**
|
|
103
|
+
* Get end of week
|
|
104
|
+
*/
|
|
105
|
+
export declare function endOfWeek(date: Date | number | string, weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6): Date;
|
|
106
|
+
/**
|
|
107
|
+
* Get start of month
|
|
108
|
+
*/
|
|
109
|
+
export declare function startOfMonth(date: Date | number | string): Date;
|
|
110
|
+
/**
|
|
111
|
+
* Get end of month
|
|
112
|
+
*/
|
|
113
|
+
export declare function endOfMonth(date: Date | number | string): Date;
|
|
114
|
+
/**
|
|
115
|
+
* Get start of year
|
|
116
|
+
*/
|
|
117
|
+
export declare function startOfYear(date: Date | number | string): Date;
|
|
118
|
+
/**
|
|
119
|
+
* Get end of year
|
|
120
|
+
*/
|
|
121
|
+
export declare function endOfYear(date: Date | number | string): Date;
|
|
122
|
+
/**
|
|
123
|
+
* Check if date is today
|
|
124
|
+
*/
|
|
125
|
+
export declare function isToday(date: Date | number | string): boolean;
|
|
126
|
+
/**
|
|
127
|
+
* Check if date is in the past
|
|
128
|
+
*/
|
|
129
|
+
export declare function isPast(date: Date | number | string): boolean;
|
|
130
|
+
/**
|
|
131
|
+
* Check if date is in the future
|
|
132
|
+
*/
|
|
133
|
+
export declare function isFuture(date: Date | number | string): boolean;
|
|
134
|
+
/**
|
|
135
|
+
* Check if date is between two dates (inclusive)
|
|
136
|
+
*/
|
|
137
|
+
export declare function isBetween(date: Date | number | string, start: Date | number | string, end: Date | number | string): boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Get difference in milliseconds between two dates
|
|
140
|
+
*/
|
|
141
|
+
export declare function diffInMilliseconds(start: Date | number | string, end: Date | number | string): number;
|
|
142
|
+
/**
|
|
143
|
+
* Get difference in seconds between two dates
|
|
144
|
+
*/
|
|
145
|
+
export declare function diffInSeconds(start: Date | number | string, end: Date | number | string): number;
|
|
146
|
+
/**
|
|
147
|
+
* Get difference in minutes between two dates
|
|
148
|
+
*/
|
|
149
|
+
export declare function diffInMinutes(start: Date | number | string, end: Date | number | string): number;
|
|
150
|
+
/**
|
|
151
|
+
* Get difference in hours between two dates
|
|
152
|
+
*/
|
|
153
|
+
export declare function diffInHours(start: Date | number | string, end: Date | number | string): number;
|
|
154
|
+
/**
|
|
155
|
+
* Get difference in days between two dates
|
|
156
|
+
*/
|
|
157
|
+
export declare function diffInDays(start: Date | number | string, end: Date | number | string): number;
|
|
158
|
+
/**
|
|
159
|
+
* Get difference in weeks between two dates
|
|
160
|
+
*/
|
|
161
|
+
export declare function diffInWeeks(start: Date | number | string, end: Date | number | string): number;
|
|
162
|
+
/**
|
|
163
|
+
* Get difference in months between two dates
|
|
164
|
+
*/
|
|
165
|
+
export declare function diffInMonths(start: Date | number | string, end: Date | number | string): number;
|
|
166
|
+
/**
|
|
167
|
+
* Get difference in years between two dates
|
|
168
|
+
*/
|
|
169
|
+
export declare function diffInYears(start: Date | number | string, end: Date | number | string): number;
|
package/dist/mod.js
ADDED
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
const dateFormatterCache = /* @__PURE__ */ new Map();
|
|
2
|
+
function getDateFormatter(locale, options) {
|
|
3
|
+
const cacheKey = `${locale ?? "default"}|${JSON.stringify(options)}`;
|
|
4
|
+
let formatter = dateFormatterCache.get(cacheKey);
|
|
5
|
+
if (!formatter) {
|
|
6
|
+
formatter = new Intl.DateTimeFormat(locale, options);
|
|
7
|
+
dateFormatterCache.set(cacheKey, formatter);
|
|
8
|
+
}
|
|
9
|
+
return formatter;
|
|
10
|
+
}
|
|
11
|
+
export function formatDate(date, options = {}) {
|
|
12
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
13
|
+
const formatOptions = {};
|
|
14
|
+
if (options.dateStyle) {
|
|
15
|
+
formatOptions.dateStyle = options.dateStyle;
|
|
16
|
+
}
|
|
17
|
+
if (options.timeStyle) {
|
|
18
|
+
formatOptions.timeStyle = options.timeStyle;
|
|
19
|
+
}
|
|
20
|
+
if (options.year) {
|
|
21
|
+
formatOptions.year = options.year;
|
|
22
|
+
}
|
|
23
|
+
if (options.month) {
|
|
24
|
+
formatOptions.month = options.month;
|
|
25
|
+
}
|
|
26
|
+
if (options.day) {
|
|
27
|
+
formatOptions.day = options.day;
|
|
28
|
+
}
|
|
29
|
+
if (options.hour !== void 0) {
|
|
30
|
+
formatOptions.hour = options.hour;
|
|
31
|
+
}
|
|
32
|
+
if (options.minute !== void 0) {
|
|
33
|
+
formatOptions.minute = options.minute;
|
|
34
|
+
}
|
|
35
|
+
if (options.second !== void 0) {
|
|
36
|
+
formatOptions.second = options.second;
|
|
37
|
+
}
|
|
38
|
+
if (options.hour12 !== void 0) {
|
|
39
|
+
formatOptions.hour12 = options.hour12;
|
|
40
|
+
}
|
|
41
|
+
const formatterOptions = {
|
|
42
|
+
...formatOptions,
|
|
43
|
+
timeZone: options.timeZone
|
|
44
|
+
};
|
|
45
|
+
return getDateFormatter(options.locale, formatterOptions).format(dateObj);
|
|
46
|
+
}
|
|
47
|
+
export function formatISO(date) {
|
|
48
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
49
|
+
return dateObj.toISOString();
|
|
50
|
+
}
|
|
51
|
+
export function formatRFC2822(date) {
|
|
52
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
53
|
+
return dateObj.toUTCString();
|
|
54
|
+
}
|
|
55
|
+
const FORMAT_PATTERNS = {
|
|
56
|
+
YYYY: /YYYY/g,
|
|
57
|
+
YY: /YY/g,
|
|
58
|
+
MM: /MM/g,
|
|
59
|
+
M: /\bM\b/g,
|
|
60
|
+
DD: /DD/g,
|
|
61
|
+
D: /\bD\b/g,
|
|
62
|
+
HH: /HH/g,
|
|
63
|
+
H: /\bH\b/g,
|
|
64
|
+
hh: /hh/g,
|
|
65
|
+
h: /\bh\b/g,
|
|
66
|
+
mm: /mm/g,
|
|
67
|
+
m: /\bm\b/g,
|
|
68
|
+
ss: /ss/g,
|
|
69
|
+
s: /\bs\b/g,
|
|
70
|
+
SSS: /SSS/g,
|
|
71
|
+
SS: /SS\b/g,
|
|
72
|
+
S: /\bS\b/g,
|
|
73
|
+
AMPM: /AM|PM/g,
|
|
74
|
+
ampm: /am|pm/g
|
|
75
|
+
};
|
|
76
|
+
export function formatCustom(date, format) {
|
|
77
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
78
|
+
const year = dateObj.getFullYear();
|
|
79
|
+
const month = dateObj.getMonth() + 1;
|
|
80
|
+
const day = dateObj.getDate();
|
|
81
|
+
const hours = dateObj.getHours();
|
|
82
|
+
const minutes = dateObj.getMinutes();
|
|
83
|
+
const seconds = dateObj.getSeconds();
|
|
84
|
+
const milliseconds = dateObj.getMilliseconds();
|
|
85
|
+
const ampm = hours >= 12 ? "PM" : "AM";
|
|
86
|
+
const hours12 = hours % 12 || 12;
|
|
87
|
+
return format.replace(FORMAT_PATTERNS.YYYY, String(year)).replace(FORMAT_PATTERNS.YY, String(year).slice(-2)).replace(FORMAT_PATTERNS.MM, String(month).padStart(2, "0")).replace(FORMAT_PATTERNS.M, String(month)).replace(FORMAT_PATTERNS.DD, String(day).padStart(2, "0")).replace(FORMAT_PATTERNS.D, String(day)).replace(FORMAT_PATTERNS.HH, String(hours).padStart(2, "0")).replace(FORMAT_PATTERNS.H, String(hours)).replace(FORMAT_PATTERNS.hh, String(hours12).padStart(2, "0")).replace(FORMAT_PATTERNS.h, String(hours12)).replace(FORMAT_PATTERNS.mm, String(minutes).padStart(2, "0")).replace(FORMAT_PATTERNS.m, String(minutes)).replace(FORMAT_PATTERNS.ss, String(seconds).padStart(2, "0")).replace(FORMAT_PATTERNS.s, String(seconds)).replace(FORMAT_PATTERNS.SSS, String(milliseconds).padStart(3, "0")).replace(
|
|
88
|
+
FORMAT_PATTERNS.SS,
|
|
89
|
+
String(Math.floor(milliseconds / 10)).padStart(2, "0")
|
|
90
|
+
).replace(FORMAT_PATTERNS.S, String(Math.floor(milliseconds / 100))).replace(FORMAT_PATTERNS.AMPM, ampm).replace(FORMAT_PATTERNS.ampm, ampm.toLowerCase());
|
|
91
|
+
}
|
|
92
|
+
export function parseDate(input) {
|
|
93
|
+
if (input instanceof Date) {
|
|
94
|
+
return input;
|
|
95
|
+
}
|
|
96
|
+
if (typeof input === "number") {
|
|
97
|
+
return new Date(input);
|
|
98
|
+
}
|
|
99
|
+
return new Date(input);
|
|
100
|
+
}
|
|
101
|
+
export function parseISO(isoString) {
|
|
102
|
+
return new Date(isoString);
|
|
103
|
+
}
|
|
104
|
+
export function isValidDate(input) {
|
|
105
|
+
try {
|
|
106
|
+
const date = parseDate(input);
|
|
107
|
+
return !Number.isNaN(date.getTime());
|
|
108
|
+
} catch {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const timezoneFormatterCache = /* @__PURE__ */ new Map();
|
|
113
|
+
function getTimezoneFormatter(timeZone) {
|
|
114
|
+
let formatter = timezoneFormatterCache.get(timeZone);
|
|
115
|
+
if (!formatter) {
|
|
116
|
+
formatter = new Intl.DateTimeFormat("en-US", {
|
|
117
|
+
timeZone,
|
|
118
|
+
year: "numeric",
|
|
119
|
+
month: "2-digit",
|
|
120
|
+
day: "2-digit",
|
|
121
|
+
hour: "2-digit",
|
|
122
|
+
minute: "2-digit",
|
|
123
|
+
second: "2-digit",
|
|
124
|
+
hour12: false
|
|
125
|
+
});
|
|
126
|
+
timezoneFormatterCache.set(timeZone, formatter);
|
|
127
|
+
}
|
|
128
|
+
return formatter;
|
|
129
|
+
}
|
|
130
|
+
export function toTimezone(date, timeZone) {
|
|
131
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
132
|
+
const formatter = getTimezoneFormatter(timeZone);
|
|
133
|
+
const parts = formatter.formatToParts(dateObj);
|
|
134
|
+
const year = Number.parseInt(
|
|
135
|
+
parts.find((p) => p.type === "year")?.value ?? "0",
|
|
136
|
+
10
|
|
137
|
+
);
|
|
138
|
+
const month = Number.parseInt(parts.find((p) => p.type === "month")?.value ?? "0", 10) - 1;
|
|
139
|
+
const day = Number.parseInt(
|
|
140
|
+
parts.find((p) => p.type === "day")?.value ?? "0",
|
|
141
|
+
10
|
|
142
|
+
);
|
|
143
|
+
const hour = Number.parseInt(
|
|
144
|
+
parts.find((p) => p.type === "hour")?.value ?? "0",
|
|
145
|
+
10
|
|
146
|
+
);
|
|
147
|
+
const minute = Number.parseInt(
|
|
148
|
+
parts.find((p) => p.type === "minute")?.value ?? "0",
|
|
149
|
+
10
|
|
150
|
+
);
|
|
151
|
+
const second = Number.parseInt(
|
|
152
|
+
parts.find((p) => p.type === "second")?.value ?? "0",
|
|
153
|
+
10
|
|
154
|
+
);
|
|
155
|
+
return new Date(Date.UTC(year, month, day, hour, minute, second));
|
|
156
|
+
}
|
|
157
|
+
export function getTimezoneOffset(date, timeZone) {
|
|
158
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
159
|
+
const utcDate = new Date(
|
|
160
|
+
dateObj.toLocaleString("en-US", { timeZone: "UTC" })
|
|
161
|
+
);
|
|
162
|
+
const tzDate = new Date(dateObj.toLocaleString("en-US", { timeZone }));
|
|
163
|
+
return (tzDate.getTime() - utcDate.getTime()) / (1e3 * 60);
|
|
164
|
+
}
|
|
165
|
+
export function getAvailableTimezones() {
|
|
166
|
+
try {
|
|
167
|
+
return Intl.supportedValuesOf("timeZone");
|
|
168
|
+
} catch {
|
|
169
|
+
return [
|
|
170
|
+
"UTC",
|
|
171
|
+
"America/New_York",
|
|
172
|
+
"America/Chicago",
|
|
173
|
+
"America/Denver",
|
|
174
|
+
"America/Los_Angeles",
|
|
175
|
+
"Europe/London",
|
|
176
|
+
"Europe/Paris",
|
|
177
|
+
"Asia/Tokyo",
|
|
178
|
+
"Asia/Shanghai",
|
|
179
|
+
"Australia/Sydney"
|
|
180
|
+
];
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
export function formatRelativeTime(date, baseDate = /* @__PURE__ */ new Date(), options = {}) {
|
|
184
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
185
|
+
const baseObj = typeof baseDate === "string" || typeof baseDate === "number" ? new Date(baseDate) : baseDate;
|
|
186
|
+
const diffMs = dateObj.getTime() - baseObj.getTime();
|
|
187
|
+
const diffSeconds = Math.floor(diffMs / 1e3);
|
|
188
|
+
const diffMinutes = Math.floor(diffSeconds / 60);
|
|
189
|
+
const diffHours = Math.floor(diffMinutes / 60);
|
|
190
|
+
const diffDays = Math.floor(diffHours / 24);
|
|
191
|
+
const diffWeeks = Math.floor(diffDays / 7);
|
|
192
|
+
const diffMonths = Math.floor(diffDays / 30);
|
|
193
|
+
const diffYears = Math.floor(diffDays / 365);
|
|
194
|
+
const rtf = new Intl.RelativeTimeFormat(options.locale, {
|
|
195
|
+
numeric: options.numeric ?? "auto",
|
|
196
|
+
style: options.style ?? "long"
|
|
197
|
+
});
|
|
198
|
+
if (Math.abs(diffYears) >= 1) {
|
|
199
|
+
return rtf.format(diffYears, "year");
|
|
200
|
+
}
|
|
201
|
+
if (Math.abs(diffMonths) >= 1) {
|
|
202
|
+
return rtf.format(diffMonths, "month");
|
|
203
|
+
}
|
|
204
|
+
if (Math.abs(diffWeeks) >= 1) {
|
|
205
|
+
return rtf.format(diffWeeks, "week");
|
|
206
|
+
}
|
|
207
|
+
if (Math.abs(diffDays) >= 1) {
|
|
208
|
+
return rtf.format(diffDays, "day");
|
|
209
|
+
}
|
|
210
|
+
if (Math.abs(diffHours) >= 1) {
|
|
211
|
+
return rtf.format(diffHours, "hour");
|
|
212
|
+
}
|
|
213
|
+
if (Math.abs(diffMinutes) >= 1) {
|
|
214
|
+
return rtf.format(diffMinutes, "minute");
|
|
215
|
+
}
|
|
216
|
+
return rtf.format(diffSeconds, "second");
|
|
217
|
+
}
|
|
218
|
+
export function getDuration(start, end) {
|
|
219
|
+
const startObj = typeof start === "string" || typeof start === "number" ? new Date(start) : start;
|
|
220
|
+
const endObj = typeof end === "string" || typeof end === "number" ? new Date(end) : end;
|
|
221
|
+
const diffMs = Math.abs(endObj.getTime() - startObj.getTime());
|
|
222
|
+
const milliseconds = diffMs % 1e3;
|
|
223
|
+
const totalSeconds = Math.floor(diffMs / 1e3);
|
|
224
|
+
const seconds = totalSeconds % 60;
|
|
225
|
+
const totalMinutes = Math.floor(totalSeconds / 60);
|
|
226
|
+
const minutes = totalMinutes % 60;
|
|
227
|
+
const totalHours = Math.floor(totalMinutes / 60);
|
|
228
|
+
const hours = totalHours % 24;
|
|
229
|
+
const totalDays = Math.floor(totalHours / 24);
|
|
230
|
+
const days = totalDays % 7;
|
|
231
|
+
const weeks = Math.floor(totalDays / 7);
|
|
232
|
+
const months = Math.floor(totalDays / 30);
|
|
233
|
+
const years = Math.floor(totalDays / 365);
|
|
234
|
+
return {
|
|
235
|
+
years: years > 0 ? years : void 0,
|
|
236
|
+
months: months > 0 ? months : void 0,
|
|
237
|
+
weeks: weeks > 0 ? weeks : void 0,
|
|
238
|
+
days: days > 0 ? days : void 0,
|
|
239
|
+
hours: hours > 0 ? hours : void 0,
|
|
240
|
+
minutes: minutes > 0 ? minutes : void 0,
|
|
241
|
+
seconds: seconds > 0 ? seconds : void 0,
|
|
242
|
+
milliseconds: milliseconds > 0 ? milliseconds : void 0
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
export function formatDuration(duration) {
|
|
246
|
+
const parts = [];
|
|
247
|
+
if (duration.years) {
|
|
248
|
+
parts.push(`${duration.years} ${duration.years === 1 ? "year" : "years"}`);
|
|
249
|
+
}
|
|
250
|
+
if (duration.months) {
|
|
251
|
+
parts.push(
|
|
252
|
+
`${duration.months} ${duration.months === 1 ? "month" : "months"}`
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
if (duration.weeks) {
|
|
256
|
+
parts.push(`${duration.weeks} ${duration.weeks === 1 ? "week" : "weeks"}`);
|
|
257
|
+
}
|
|
258
|
+
if (duration.days) {
|
|
259
|
+
parts.push(`${duration.days} ${duration.days === 1 ? "day" : "days"}`);
|
|
260
|
+
}
|
|
261
|
+
if (duration.hours) {
|
|
262
|
+
parts.push(`${duration.hours} ${duration.hours === 1 ? "hour" : "hours"}`);
|
|
263
|
+
}
|
|
264
|
+
if (duration.minutes) {
|
|
265
|
+
parts.push(
|
|
266
|
+
`${duration.minutes} ${duration.minutes === 1 ? "minute" : "minutes"}`
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
if (duration.seconds) {
|
|
270
|
+
parts.push(
|
|
271
|
+
`${duration.seconds} ${duration.seconds === 1 ? "second" : "seconds"}`
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
if (duration.milliseconds) {
|
|
275
|
+
parts.push(
|
|
276
|
+
`${duration.milliseconds} ${duration.milliseconds === 1 ? "millisecond" : "milliseconds"}`
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
if (parts.length === 0) {
|
|
280
|
+
return "0 seconds";
|
|
281
|
+
}
|
|
282
|
+
if (parts.length === 1) {
|
|
283
|
+
const first = parts[0];
|
|
284
|
+
if (first === void 0) {
|
|
285
|
+
return "0 seconds";
|
|
286
|
+
}
|
|
287
|
+
return first;
|
|
288
|
+
}
|
|
289
|
+
if (parts.length === 2) {
|
|
290
|
+
return `${parts[0]} and ${parts[1]}`;
|
|
291
|
+
}
|
|
292
|
+
return `${parts.slice(0, -1).join(", ")}, and ${parts[parts.length - 1]}`;
|
|
293
|
+
}
|
|
294
|
+
export function addDuration(date, duration) {
|
|
295
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
296
|
+
const result = new Date(dateObj);
|
|
297
|
+
if (duration.years) {
|
|
298
|
+
result.setFullYear(result.getFullYear() + duration.years);
|
|
299
|
+
}
|
|
300
|
+
if (duration.months) {
|
|
301
|
+
result.setMonth(result.getMonth() + duration.months);
|
|
302
|
+
}
|
|
303
|
+
if (duration.weeks) {
|
|
304
|
+
result.setDate(result.getDate() + duration.weeks * 7);
|
|
305
|
+
}
|
|
306
|
+
if (duration.days) {
|
|
307
|
+
result.setDate(result.getDate() + duration.days);
|
|
308
|
+
}
|
|
309
|
+
if (duration.hours) {
|
|
310
|
+
result.setHours(result.getHours() + duration.hours);
|
|
311
|
+
}
|
|
312
|
+
if (duration.minutes) {
|
|
313
|
+
result.setMinutes(result.getMinutes() + duration.minutes);
|
|
314
|
+
}
|
|
315
|
+
if (duration.seconds) {
|
|
316
|
+
result.setSeconds(result.getSeconds() + duration.seconds);
|
|
317
|
+
}
|
|
318
|
+
if (duration.milliseconds) {
|
|
319
|
+
result.setMilliseconds(result.getMilliseconds() + duration.milliseconds);
|
|
320
|
+
}
|
|
321
|
+
return result;
|
|
322
|
+
}
|
|
323
|
+
export function subtractDuration(date, duration) {
|
|
324
|
+
const negatedDuration = {};
|
|
325
|
+
if (duration.years) negatedDuration.years = -duration.years;
|
|
326
|
+
if (duration.months) negatedDuration.months = -duration.months;
|
|
327
|
+
if (duration.weeks) negatedDuration.weeks = -duration.weeks;
|
|
328
|
+
if (duration.days) negatedDuration.days = -duration.days;
|
|
329
|
+
if (duration.hours) negatedDuration.hours = -duration.hours;
|
|
330
|
+
if (duration.minutes) negatedDuration.minutes = -duration.minutes;
|
|
331
|
+
if (duration.seconds) negatedDuration.seconds = -duration.seconds;
|
|
332
|
+
if (duration.milliseconds) {
|
|
333
|
+
negatedDuration.milliseconds = -duration.milliseconds;
|
|
334
|
+
}
|
|
335
|
+
return addDuration(date, negatedDuration);
|
|
336
|
+
}
|
|
337
|
+
export function startOfDay(date) {
|
|
338
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
339
|
+
const result = new Date(dateObj);
|
|
340
|
+
result.setHours(0, 0, 0, 0);
|
|
341
|
+
return result;
|
|
342
|
+
}
|
|
343
|
+
export function endOfDay(date) {
|
|
344
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
345
|
+
const result = new Date(dateObj);
|
|
346
|
+
result.setHours(23, 59, 59, 999);
|
|
347
|
+
return result;
|
|
348
|
+
}
|
|
349
|
+
export function startOfWeek(date, weekStartsOn = 0) {
|
|
350
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
351
|
+
const result = new Date(dateObj);
|
|
352
|
+
const day = result.getDay();
|
|
353
|
+
const diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;
|
|
354
|
+
result.setDate(result.getDate() - diff);
|
|
355
|
+
return startOfDay(result);
|
|
356
|
+
}
|
|
357
|
+
export function endOfWeek(date, weekStartsOn = 0) {
|
|
358
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
359
|
+
const start = startOfWeek(dateObj, weekStartsOn);
|
|
360
|
+
const result = new Date(start);
|
|
361
|
+
result.setDate(result.getDate() + 6);
|
|
362
|
+
return endOfDay(result);
|
|
363
|
+
}
|
|
364
|
+
export function startOfMonth(date) {
|
|
365
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
366
|
+
const result = new Date(dateObj);
|
|
367
|
+
result.setDate(1);
|
|
368
|
+
return startOfDay(result);
|
|
369
|
+
}
|
|
370
|
+
export function endOfMonth(date) {
|
|
371
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
372
|
+
const result = new Date(dateObj);
|
|
373
|
+
result.setMonth(result.getMonth() + 1, 0);
|
|
374
|
+
return endOfDay(result);
|
|
375
|
+
}
|
|
376
|
+
export function startOfYear(date) {
|
|
377
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
378
|
+
const result = new Date(dateObj);
|
|
379
|
+
result.setMonth(0, 1);
|
|
380
|
+
return startOfDay(result);
|
|
381
|
+
}
|
|
382
|
+
export function endOfYear(date) {
|
|
383
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
384
|
+
const result = new Date(dateObj);
|
|
385
|
+
result.setMonth(11, 31);
|
|
386
|
+
return endOfDay(result);
|
|
387
|
+
}
|
|
388
|
+
export function isToday(date) {
|
|
389
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
390
|
+
const today = startOfDay(/* @__PURE__ */ new Date());
|
|
391
|
+
const checkDate = startOfDay(dateObj);
|
|
392
|
+
return today.getTime() === checkDate.getTime();
|
|
393
|
+
}
|
|
394
|
+
export function isPast(date) {
|
|
395
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
396
|
+
return dateObj.getTime() < Date.now();
|
|
397
|
+
}
|
|
398
|
+
export function isFuture(date) {
|
|
399
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
400
|
+
return dateObj.getTime() > Date.now();
|
|
401
|
+
}
|
|
402
|
+
export function isBetween(date, start, end) {
|
|
403
|
+
const dateObj = typeof date === "string" || typeof date === "number" ? new Date(date) : date;
|
|
404
|
+
const startObj = typeof start === "string" || typeof start === "number" ? new Date(start) : start;
|
|
405
|
+
const endObj = typeof end === "string" || typeof end === "number" ? new Date(end) : end;
|
|
406
|
+
const time = dateObj.getTime();
|
|
407
|
+
const startTime = startObj.getTime();
|
|
408
|
+
const endTime = endObj.getTime();
|
|
409
|
+
return time >= startTime && time <= endTime;
|
|
410
|
+
}
|
|
411
|
+
export function diffInMilliseconds(start, end) {
|
|
412
|
+
const startObj = typeof start === "string" || typeof start === "number" ? new Date(start) : start;
|
|
413
|
+
const endObj = typeof end === "string" || typeof end === "number" ? new Date(end) : end;
|
|
414
|
+
return endObj.getTime() - startObj.getTime();
|
|
415
|
+
}
|
|
416
|
+
export function diffInSeconds(start, end) {
|
|
417
|
+
return Math.floor(diffInMilliseconds(start, end) / 1e3);
|
|
418
|
+
}
|
|
419
|
+
export function diffInMinutes(start, end) {
|
|
420
|
+
return Math.floor(diffInSeconds(start, end) / 60);
|
|
421
|
+
}
|
|
422
|
+
export function diffInHours(start, end) {
|
|
423
|
+
return Math.floor(diffInMinutes(start, end) / 60);
|
|
424
|
+
}
|
|
425
|
+
export function diffInDays(start, end) {
|
|
426
|
+
return Math.floor(diffInHours(start, end) / 24);
|
|
427
|
+
}
|
|
428
|
+
export function diffInWeeks(start, end) {
|
|
429
|
+
return Math.floor(diffInDays(start, end) / 7);
|
|
430
|
+
}
|
|
431
|
+
export function diffInMonths(start, end) {
|
|
432
|
+
const startObj = typeof start === "string" || typeof start === "number" ? new Date(start) : start;
|
|
433
|
+
const endObj = typeof end === "string" || typeof end === "number" ? new Date(end) : end;
|
|
434
|
+
const years = endObj.getFullYear() - startObj.getFullYear();
|
|
435
|
+
const months = endObj.getMonth() - startObj.getMonth();
|
|
436
|
+
return years * 12 + months;
|
|
437
|
+
}
|
|
438
|
+
export function diffInYears(start, end) {
|
|
439
|
+
const startObj = typeof start === "string" || typeof start === "number" ? new Date(start) : start;
|
|
440
|
+
const endObj = typeof end === "string" || typeof end === "number" ? new Date(end) : end;
|
|
441
|
+
return endObj.getFullYear() - startObj.getFullYear();
|
|
442
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@reliverse/datetime",
|
|
3
|
+
"description": "DateTime manipulation and formatting utilities for Reliverse ecosystem",
|
|
4
|
+
"author": "reliverse",
|
|
5
|
+
"version": "2.2.7",
|
|
6
|
+
"private": false,
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "./src/mod.ts",
|
|
9
|
+
"types": "./src/mod.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/mod.d.ts",
|
|
13
|
+
"default": "./dist/mod.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"package.json"
|
|
22
|
+
],
|
|
23
|
+
"license": "MIT"
|
|
24
|
+
}
|