date-vir 2.0.0 → 4.0.0
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/cjs/date-operations/diff-dates.js +57 -18
- package/dist/cjs/duration.js +39 -0
- package/dist/cjs/extra-utils/has-date-props.js +25 -0
- package/dist/cjs/extra-utils/js-date-conversion.js +2 -2
- package/dist/cjs/extra-utils/now.js +2 -2
- package/dist/cjs/formatting/formatted-string.js +34 -0
- package/dist/cjs/formatting/html-input.js +37 -0
- package/dist/cjs/formatting/relative-string.js +52 -0
- package/dist/cjs/formatting/simple-strings.js +58 -0
- package/dist/cjs/formatting/timestamp.js +21 -0
- package/dist/cjs/index.js +7 -2
- package/dist/esm/date-operations/diff-dates.d.ts +22 -20
- package/dist/esm/date-operations/diff-dates.js +55 -17
- package/dist/esm/duration.d.ts +50 -6
- package/dist/esm/duration.js +38 -1
- package/dist/esm/extra-utils/has-date-props.d.ts +8 -0
- package/dist/esm/extra-utils/has-date-props.js +20 -0
- package/dist/esm/extra-utils/js-date-conversion.js +1 -1
- package/dist/esm/extra-utils/now.d.ts +1 -1
- package/dist/esm/extra-utils/now.js +1 -1
- package/dist/esm/extra-utils/zero.d.ts +1 -1
- package/dist/esm/formatting/formatted-string.d.ts +14 -0
- package/dist/esm/formatting/formatted-string.js +29 -0
- package/dist/esm/{full-date/primitive-conversions.d.ts → formatting/html-input.d.ts} +2 -19
- package/dist/esm/formatting/html-input.js +33 -0
- package/dist/esm/formatting/relative-string.d.ts +25 -0
- package/dist/esm/formatting/relative-string.js +48 -0
- package/dist/esm/formatting/simple-strings.d.ts +71 -0
- package/dist/esm/formatting/simple-strings.js +51 -0
- package/dist/esm/formatting/timestamp.d.ts +6 -0
- package/dist/esm/formatting/timestamp.js +16 -0
- package/dist/esm/full-date/full-date-shape.d.ts +4 -4
- package/dist/esm/index.d.ts +7 -2
- package/dist/esm/index.js +7 -2
- package/package.json +33 -31
- package/public/index.css +7 -0
- package/dist/cjs/full-date/primitive-conversions.js +0 -102
- package/dist/esm/full-date/primitive-conversions.js +0 -94
- package/docs-dist/assets/highlight.css +0 -92
- package/docs-dist/assets/main.js +0 -59
- package/docs-dist/assets/navigation.js +0 -1
- package/docs-dist/assets/search.js +0 -1
- package/docs-dist/assets/style.css +0 -1383
- package/docs-dist/enums/DiffUnit.html +0 -126
- package/docs-dist/enums/FullDatePartEnum.html +0 -102
- package/docs-dist/functions/assertIsValidFullDate.html +0 -72
- package/docs-dist/functions/assertValidTimezone.html +0 -78
- package/docs-dist/functions/calculateRelativeDate.html +0 -78
- package/docs-dist/functions/clearParts.html +0 -74
- package/docs-dist/functions/clearTime.html +0 -72
- package/docs-dist/functions/combineDateParts.html +0 -197
- package/docs-dist/functions/createFullDate.html +0 -89
- package/docs-dist/functions/createFullDateInUserTimezone.html +0 -72
- package/docs-dist/functions/createUtcFullDate.html +0 -72
- package/docs-dist/functions/diffDates.html +0 -84
- package/docs-dist/functions/getNowFullDate.html +0 -77
- package/docs-dist/functions/getNowInIsoString.html +0 -67
- package/docs-dist/functions/getNowInUserTimezone.html +0 -67
- package/docs-dist/functions/hasTimezone.html +0 -79
- package/docs-dist/functions/isDateAfter.html +0 -77
- package/docs-dist/functions/isValidFullDate.html +0 -72
- package/docs-dist/functions/isValidIsoString.html +0 -72
- package/docs-dist/functions/isValidTimezone.html +0 -78
- package/docs-dist/functions/overrideDateParts.html +0 -77
- package/docs-dist/functions/parseInputElementValue.html +0 -83
- package/docs-dist/functions/parseLuxonDateTime.html +0 -84
- package/docs-dist/functions/parseStrangeString.html +0 -96
- package/docs-dist/functions/toFormattedString.html +0 -82
- package/docs-dist/functions/toHtmlInputString.html +0 -193
- package/docs-dist/functions/toIsoString.html +0 -75
- package/docs-dist/functions/toJsDate.html +0 -72
- package/docs-dist/functions/toLocaleString.html +0 -77
- package/docs-dist/functions/toLuxonDateTime.html +0 -77
- package/docs-dist/functions/toNewTimezone.html +0 -83
- package/docs-dist/functions/toTimestamp.html +0 -75
- package/docs-dist/modules.html +0 -139
- package/docs-dist/types/AnyDuration.html +0 -66
- package/docs-dist/types/DateFullDateKeys.html +0 -63
- package/docs-dist/types/DateLike.html +0 -66
- package/docs-dist/types/DatePart.html +0 -68
- package/docs-dist/types/DateTimeString.html +0 -63
- package/docs-dist/types/DateTimeWithSeconds.html +0 -63
- package/docs-dist/types/Duration.html +0 -73
- package/docs-dist/types/FullDate.html +0 -77
- package/docs-dist/types/JustDateString.html +0 -63
- package/docs-dist/types/JustTimeString.html +0 -63
- package/docs-dist/types/JustTimeWithSecondsString.html +0 -63
- package/docs-dist/types/MaybeDatePart.html +0 -66
- package/docs-dist/types/MaybeTuple.html +0 -68
- package/docs-dist/types/OnlyDatePart.html +0 -63
- package/docs-dist/types/OnlyHourMinutePart.html +0 -63
- package/docs-dist/types/OnlyHourMinuteSecondPart.html +0 -63
- package/docs-dist/types/TimeFullDateKeys.html +0 -63
- package/docs-dist/types/TimePart.html +0 -68
- package/docs-dist/types/Timezone.html +0 -63
- package/docs-dist/types/Timezones.html +0 -63
- package/docs-dist/types/UtcIsoString.html +0 -63
- package/docs-dist/types/UtcTimezone.html +0 -63
- package/docs-dist/variables/allTimezoneNames.html +0 -68
- package/docs-dist/variables/dateFullDateKeys-1.html +0 -63
- package/docs-dist/variables/datePartShape.html +0 -89
- package/docs-dist/variables/formatPresets.html +0 -114
- package/docs-dist/variables/fullDateShape.html +0 -63
- package/docs-dist/variables/timeFullDateKeys-1.html +0 -63
- package/docs-dist/variables/timePartShape.html +0 -91
- package/docs-dist/variables/timezones-1.html +0 -1005
- package/docs-dist/variables/userLocale.html +0 -63
- package/docs-dist/variables/userTimezone.html +0 -66
- package/docs-dist/variables/utcTimezone-1.html +0 -66
- package/docs-dist/variables/zeroDate.html +0 -80
- package/docs-dist/variables/zeroTime.html +0 -63
- /package/dist/cjs/{full-date → formatting}/string-format-types.js +0 -0
- /package/dist/esm/{full-date → formatting}/string-format-types.d.ts +0 -0
- /package/dist/esm/{full-date → formatting}/string-format-types.js +0 -0
|
@@ -1,32 +1,71 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isDateAfter = exports.
|
|
3
|
+
exports.isDateAfter = exports.diffDatesAllUnits = exports.diffDates = void 0;
|
|
4
|
+
const common_1 = require("@augment-vir/common");
|
|
5
|
+
const duration_1 = require("../duration");
|
|
4
6
|
const luxon_date_time_conversion_1 = require("../full-date/luxon-date-time-conversion");
|
|
7
|
+
const conversionAccuracies = {
|
|
8
|
+
[duration_1.DurationUnit.Years]: 'longterm',
|
|
9
|
+
[duration_1.DurationUnit.Quarters]: 'longterm',
|
|
10
|
+
[duration_1.DurationUnit.Months]: 'longterm',
|
|
11
|
+
[duration_1.DurationUnit.Weeks]: 'casual',
|
|
12
|
+
[duration_1.DurationUnit.Days]: 'casual',
|
|
13
|
+
[duration_1.DurationUnit.Hours]: 'casual',
|
|
14
|
+
[duration_1.DurationUnit.Minutes]: 'casual',
|
|
15
|
+
[duration_1.DurationUnit.Seconds]: 'casual',
|
|
16
|
+
[duration_1.DurationUnit.Milliseconds]: 'casual',
|
|
17
|
+
};
|
|
5
18
|
/**
|
|
6
|
-
*
|
|
7
|
-
* causing inaccuracies and many issues. See
|
|
8
|
-
* https://moment.github.io/luxon/#/math?id=casual-vs-longterm-conversion-accuracy for more info.
|
|
19
|
+
* Diffs two dates and returns the diff in the specific unit.
|
|
9
20
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
21
|
+
* Note: when years, quarters, or months are used for the unit then "long term" durations are used
|
|
22
|
+
* to calculate the diff. See more details here:
|
|
23
|
+
* https://moment.github.io/luxon/#/math?id=casual-vs-longterm-conversion-accuracy
|
|
12
24
|
*/
|
|
13
|
-
var DiffUnit;
|
|
14
|
-
(function (DiffUnit) {
|
|
15
|
-
DiffUnit["Weeks"] = "weeks";
|
|
16
|
-
DiffUnit["Days"] = "days";
|
|
17
|
-
DiffUnit["Hours"] = "hours";
|
|
18
|
-
DiffUnit["Minutes"] = "minutes";
|
|
19
|
-
DiffUnit["Seconds"] = "seconds";
|
|
20
|
-
DiffUnit["Milliseconds"] = "milliseconds";
|
|
21
|
-
})(DiffUnit || (exports.DiffUnit = DiffUnit = {}));
|
|
22
25
|
function diffDates({ start, end, unit, }) {
|
|
23
26
|
const luxonDateStart = (0, luxon_date_time_conversion_1.toLuxonDateTime)(start);
|
|
24
27
|
const luxonDateEnd = (0, luxon_date_time_conversion_1.toLuxonDateTime)(end);
|
|
25
|
-
const diff = luxonDateEnd
|
|
28
|
+
const diff = luxonDateEnd
|
|
29
|
+
.diff(luxonDateStart, unit, {
|
|
30
|
+
conversionAccuracy: conversionAccuracies[unit],
|
|
31
|
+
})
|
|
32
|
+
.toObject();
|
|
26
33
|
return diff;
|
|
27
34
|
}
|
|
28
35
|
exports.diffDates = diffDates;
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Diffs two dates and returns that diff in each unit. Note that the unit in the returned object are
|
|
38
|
+
* not meant to be added together, each unit is instead the same value but calculated in that given
|
|
39
|
+
* unit.
|
|
40
|
+
*
|
|
41
|
+
* Note: when years, quarters, or months are used for the unit then "long term" durations are used
|
|
42
|
+
* to calculate the diff. See more details here:
|
|
43
|
+
* https://moment.github.io/luxon/#/math?id=casual-vs-longterm-conversion-accuracy
|
|
44
|
+
*/
|
|
45
|
+
function diffDatesAllUnits({ start, end }) {
|
|
46
|
+
const allUnitDiffEntries = duration_1.orderedDurationUnits.map((durationUnit) => {
|
|
47
|
+
const diff = diffDates({
|
|
48
|
+
start,
|
|
49
|
+
end,
|
|
50
|
+
unit: durationUnit,
|
|
51
|
+
});
|
|
52
|
+
const duration = diff[durationUnit];
|
|
53
|
+
/** Ignore this edge case in coverage cause its for type guarding. */
|
|
54
|
+
/* c8 ignore next 5 */
|
|
55
|
+
if (duration == undefined) {
|
|
56
|
+
throw new Error(`Internal date-vir error: failed to find duration for '${durationUnit}'`);
|
|
57
|
+
}
|
|
58
|
+
return [
|
|
59
|
+
durationUnit,
|
|
60
|
+
duration,
|
|
61
|
+
];
|
|
62
|
+
});
|
|
63
|
+
const allDurations = (0, common_1.typedObjectFromEntries)(allUnitDiffEntries);
|
|
64
|
+
return allDurations;
|
|
65
|
+
}
|
|
66
|
+
exports.diffDatesAllUnits = diffDatesAllUnits;
|
|
67
|
+
function isDateAfter({ relativeTo, fullDate, }) {
|
|
68
|
+
return (diffDates({ start: relativeTo, end: fullDate, unit: duration_1.DurationUnit.Milliseconds })
|
|
69
|
+
.milliseconds >= 0);
|
|
31
70
|
}
|
|
32
71
|
exports.isDateAfter = isDateAfter;
|
package/dist/cjs/duration.js
CHANGED
|
@@ -1,2 +1,41 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.orderedDurationUnits = exports.singularDurationUnitNames = exports.DurationUnit = void 0;
|
|
4
|
+
var DurationUnit;
|
|
5
|
+
(function (DurationUnit) {
|
|
6
|
+
DurationUnit["Years"] = "years";
|
|
7
|
+
DurationUnit["Quarters"] = "quarters";
|
|
8
|
+
DurationUnit["Months"] = "months";
|
|
9
|
+
DurationUnit["Weeks"] = "weeks";
|
|
10
|
+
DurationUnit["Days"] = "days";
|
|
11
|
+
DurationUnit["Hours"] = "hours";
|
|
12
|
+
DurationUnit["Minutes"] = "minutes";
|
|
13
|
+
DurationUnit["Seconds"] = "seconds";
|
|
14
|
+
DurationUnit["Milliseconds"] = "milliseconds";
|
|
15
|
+
})(DurationUnit || (exports.DurationUnit = DurationUnit = {}));
|
|
16
|
+
exports.singularDurationUnitNames = {
|
|
17
|
+
[DurationUnit.Milliseconds]: 'millisecond',
|
|
18
|
+
[DurationUnit.Seconds]: 'second',
|
|
19
|
+
[DurationUnit.Minutes]: 'minute',
|
|
20
|
+
[DurationUnit.Hours]: 'hour',
|
|
21
|
+
[DurationUnit.Days]: 'day',
|
|
22
|
+
[DurationUnit.Weeks]: 'week',
|
|
23
|
+
[DurationUnit.Months]: 'month',
|
|
24
|
+
[DurationUnit.Quarters]: 'quarter',
|
|
25
|
+
[DurationUnit.Years]: 'year',
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Array of DurationUnit values: from smallest unit (milliseconds at index 0) to longest unit
|
|
29
|
+
* (years).
|
|
30
|
+
*/
|
|
31
|
+
exports.orderedDurationUnits = [
|
|
32
|
+
DurationUnit.Milliseconds,
|
|
33
|
+
DurationUnit.Seconds,
|
|
34
|
+
DurationUnit.Minutes,
|
|
35
|
+
DurationUnit.Hours,
|
|
36
|
+
DurationUnit.Days,
|
|
37
|
+
DurationUnit.Weeks,
|
|
38
|
+
DurationUnit.Months,
|
|
39
|
+
DurationUnit.Quarters,
|
|
40
|
+
DurationUnit.Years,
|
|
41
|
+
];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.assertHasDateProps = exports.hasDateProps = void 0;
|
|
4
|
+
function hasDateProps(dateInput, keys) {
|
|
5
|
+
try {
|
|
6
|
+
assertHasDateProps(dateInput, keys);
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
catch (error) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.hasDateProps = hasDateProps;
|
|
14
|
+
function assertHasDateProps(dateInput, keys) {
|
|
15
|
+
const missingKeys = [];
|
|
16
|
+
keys.forEach((key) => {
|
|
17
|
+
if (dateInput[key] == undefined) {
|
|
18
|
+
missingKeys.push(key);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
if (missingKeys.length) {
|
|
22
|
+
throw new Error(`Missing required FullDate key(s): ${missingKeys.join(', ')}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.assertHasDateProps = assertHasDateProps;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.toJsDate = void 0;
|
|
4
|
-
const
|
|
4
|
+
const timestamp_1 = require("../formatting/timestamp");
|
|
5
5
|
function toJsDate(fullDate) {
|
|
6
|
-
return new Date((0,
|
|
6
|
+
return new Date((0, timestamp_1.toTimestamp)(fullDate));
|
|
7
7
|
}
|
|
8
8
|
exports.toJsDate = toJsDate;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getNowInUserTimezone = exports.getNowInIsoString = void 0;
|
|
4
|
+
const timestamp_1 = require("../formatting/timestamp");
|
|
4
5
|
const create_full_date_1 = require("../full-date/create-full-date");
|
|
5
|
-
const primitive_conversions_1 = require("../full-date/primitive-conversions");
|
|
6
6
|
const timezones_1 = require("../timezone/timezones");
|
|
7
7
|
function getNowInIsoString() {
|
|
8
8
|
/**
|
|
9
9
|
* The time zone doesn't matter here because the ISO string will be identical for a given date
|
|
10
10
|
* no matter what its timezone is.
|
|
11
11
|
*/
|
|
12
|
-
return (0,
|
|
12
|
+
return (0, timestamp_1.toIsoString)((0, create_full_date_1.getNowFullDate)(timezones_1.utcTimezone));
|
|
13
13
|
}
|
|
14
14
|
exports.getNowInIsoString = getNowInIsoString;
|
|
15
15
|
function getNowInUserTimezone() {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toFormattedString = exports.toLocaleString = void 0;
|
|
4
|
+
const luxon_date_time_conversion_1 = require("../full-date/luxon-date-time-conversion");
|
|
5
|
+
const locales_1 = require("../locales");
|
|
6
|
+
/**
|
|
7
|
+
* Chromium has a weird behavior where the "NARROW NO-BREAK SPACE" character (code 8239) is used
|
|
8
|
+
* instead of a space (code 32) before AM/PM.
|
|
9
|
+
*/
|
|
10
|
+
function fixChromiumSpace(original) {
|
|
11
|
+
return original.replace(new RegExp(String.fromCharCode(8239), 'g'), ' ');
|
|
12
|
+
}
|
|
13
|
+
/** Converts the given FullDate into a string in the user's locale, or the given localeOverride. */
|
|
14
|
+
function toLocaleString(fullDate, formatOptions) {
|
|
15
|
+
const localeString = (0, luxon_date_time_conversion_1.toLuxonDateTime)(fullDate).toLocaleString({
|
|
16
|
+
...formatOptions,
|
|
17
|
+
}, {
|
|
18
|
+
locale: formatOptions?.locale ?? locales_1.userLocale,
|
|
19
|
+
});
|
|
20
|
+
return fixChromiumSpace(localeString);
|
|
21
|
+
}
|
|
22
|
+
exports.toLocaleString = toLocaleString;
|
|
23
|
+
/**
|
|
24
|
+
* Provides arbitrary date formatting using Luxon. For full details on the options for the format
|
|
25
|
+
* string input, see https://moment.github.io/luxon/#/formatting?id=table-of-tokens
|
|
26
|
+
*
|
|
27
|
+
* You probably should **prefer toLocaleString** so your users see the format they expect. It
|
|
28
|
+
* already has many formatting options.
|
|
29
|
+
*/
|
|
30
|
+
function toFormattedString(fullDate, format, localeOverride = locales_1.userLocale) {
|
|
31
|
+
const formattedString = (0, luxon_date_time_conversion_1.toLuxonDateTime)(fullDate).toFormat(format, { locale: localeOverride });
|
|
32
|
+
return fixChromiumSpace(formattedString);
|
|
33
|
+
}
|
|
34
|
+
exports.toFormattedString = toFormattedString;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toHtmlInputString = void 0;
|
|
4
|
+
const common_1 = require("@augment-vir/common");
|
|
5
|
+
const has_date_props_1 = require("../extra-utils/has-date-props");
|
|
6
|
+
const full_date_shape_1 = require("../full-date/full-date-shape");
|
|
7
|
+
const simple_strings_1 = require("./simple-strings");
|
|
8
|
+
function toHtmlInputString(fullDate, inputType, includeSeconds) {
|
|
9
|
+
const internalFullDate = fullDate;
|
|
10
|
+
if (inputType === full_date_shape_1.FullDatePartEnum.Date) {
|
|
11
|
+
(0, has_date_props_1.assertHasDateProps)(internalFullDate, [
|
|
12
|
+
'year',
|
|
13
|
+
'month',
|
|
14
|
+
'day',
|
|
15
|
+
]);
|
|
16
|
+
return (0, simple_strings_1.toSimpleDatePartString)(internalFullDate);
|
|
17
|
+
}
|
|
18
|
+
else if (inputType === full_date_shape_1.FullDatePartEnum.Time) {
|
|
19
|
+
if (includeSeconds && internalFullDate.second == undefined) {
|
|
20
|
+
throw new Error('Tried to include seconds in the time string but no seconds were provided.');
|
|
21
|
+
}
|
|
22
|
+
(0, has_date_props_1.assertHasDateProps)(internalFullDate, [
|
|
23
|
+
'hour',
|
|
24
|
+
'minute',
|
|
25
|
+
]);
|
|
26
|
+
return (0, simple_strings_1.toSimpleTimePartString)(internalFullDate, !!includeSeconds);
|
|
27
|
+
}
|
|
28
|
+
else if (inputType === full_date_shape_1.FullDatePartEnum.DateTime) {
|
|
29
|
+
const datePart = toHtmlInputString(fullDate, full_date_shape_1.FullDatePartEnum.Date);
|
|
30
|
+
const timePart = toHtmlInputString(fullDate, full_date_shape_1.FullDatePartEnum.Time, includeSeconds);
|
|
31
|
+
return `${datePart}T${timePart}`;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
throw new Error(`Unexpected inputTyped: '${inputType}'. Expected usage of FullDatePartEnum or one of ${(0, common_1.getEnumTypedValues)(full_date_shape_1.FullDatePartEnum).join(', ')}.`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.toHtmlInputString = toHtmlInputString;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toRelativeString = void 0;
|
|
4
|
+
const common_1 = require("@augment-vir/common");
|
|
5
|
+
const diff_dates_1 = require("../date-operations/diff-dates");
|
|
6
|
+
const duration_1 = require("../duration");
|
|
7
|
+
function toRelativeString({ fullDate, relativeTo, options = {}, }) {
|
|
8
|
+
const allUnitDiffs = (0, diff_dates_1.diffDatesAllUnits)({
|
|
9
|
+
start: fullDate,
|
|
10
|
+
end: relativeTo,
|
|
11
|
+
});
|
|
12
|
+
const unitsWithinBounds = (0, common_1.mapObjectValues)(allUnitDiffs, (durationUnit, duration) => {
|
|
13
|
+
const isAboveZero = Math.floor(Math.abs(duration)) > 0;
|
|
14
|
+
return isAboveZero;
|
|
15
|
+
});
|
|
16
|
+
const unitToUse = duration_1.orderedDurationUnits.reduce((chosenUnit, currentUnit) => {
|
|
17
|
+
const isUnitAllowed = !options.blockedRelativeUnits?.includes(currentUnit);
|
|
18
|
+
if (isUnitAllowed && unitsWithinBounds[currentUnit]) {
|
|
19
|
+
return currentUnit;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
return chosenUnit;
|
|
23
|
+
}
|
|
24
|
+
}, undefined);
|
|
25
|
+
const shouldUseJustNow = options.blockJustNow
|
|
26
|
+
? false
|
|
27
|
+
: (unitToUse === duration_1.DurationUnit.Minutes && allUnitDiffs.minutes < 2) ||
|
|
28
|
+
(unitToUse === duration_1.DurationUnit.Seconds && allUnitDiffs.seconds < 11) ||
|
|
29
|
+
(unitToUse === duration_1.DurationUnit.Milliseconds && allUnitDiffs.milliseconds < 710);
|
|
30
|
+
/** Some short circuits. */
|
|
31
|
+
if (unitToUse == undefined) {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
else if (shouldUseJustNow) {
|
|
35
|
+
return 'just now';
|
|
36
|
+
}
|
|
37
|
+
const duration = allUnitDiffs[unitToUse];
|
|
38
|
+
const roundedAbsoluteDuration = Math.abs((0, common_1.round)({ digits: options.decimalDigitCount || 0, number: duration }));
|
|
39
|
+
const isDurationSingular = roundedAbsoluteDuration === 1;
|
|
40
|
+
const unitName = [
|
|
41
|
+
duration_1.singularDurationUnitNames[unitToUse],
|
|
42
|
+
isDurationSingular ? '' : 's',
|
|
43
|
+
].join('');
|
|
44
|
+
const value = isDurationSingular ? 'a' : roundedAbsoluteDuration;
|
|
45
|
+
if (duration < 0) {
|
|
46
|
+
return `in ${value} ${unitName}`;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
return `${value} ${unitName} ago`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.toRelativeString = toRelativeString;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toSimpleString = exports.toSimplePartStrings = exports.toSimpleTimePartString = exports.toSimpleDatePartString = void 0;
|
|
4
|
+
const common_1 = require("@augment-vir/common");
|
|
5
|
+
/**
|
|
6
|
+
* Create a string based on just the date parts of a FullDate.
|
|
7
|
+
*
|
|
8
|
+
* CAUTION: this does not user locale setting and should therefore not be used for user-facing date
|
|
9
|
+
* formatting. Prefer using `toLocaleString` instead for user-facing strings.
|
|
10
|
+
*
|
|
11
|
+
* Example output: `'2023-12-05'`
|
|
12
|
+
*/
|
|
13
|
+
function toSimpleDatePartString(fullDate) {
|
|
14
|
+
const dateParts = [
|
|
15
|
+
String(Math.abs(fullDate.year)).padStart(4, '0'),
|
|
16
|
+
String(Math.abs(fullDate.month)).padStart(2, '0'),
|
|
17
|
+
String(Math.abs(fullDate.day)).padStart(2, '0'),
|
|
18
|
+
];
|
|
19
|
+
const dateString = dateParts.join('-');
|
|
20
|
+
return dateString;
|
|
21
|
+
}
|
|
22
|
+
exports.toSimpleDatePartString = toSimpleDatePartString;
|
|
23
|
+
function toSimpleTimePartString(fullDate, includeSeconds) {
|
|
24
|
+
const seconds = (0, common_1.typedHasProperty)(fullDate, 'second') && includeSeconds
|
|
25
|
+
? String(Math.abs(fullDate.second)).padStart(2, '0')
|
|
26
|
+
: undefined;
|
|
27
|
+
const timeParts = [
|
|
28
|
+
String(Math.abs(fullDate.hour)).padStart(2, '0'),
|
|
29
|
+
String(Math.abs(fullDate.minute)).padStart(2, '0'),
|
|
30
|
+
seconds,
|
|
31
|
+
].filter(common_1.isTruthy);
|
|
32
|
+
return timeParts.join(':');
|
|
33
|
+
}
|
|
34
|
+
exports.toSimpleTimePartString = toSimpleTimePartString;
|
|
35
|
+
function toSimplePartStrings(fullDate, options) {
|
|
36
|
+
return {
|
|
37
|
+
date: toSimpleDatePartString(fullDate),
|
|
38
|
+
time: toSimpleTimePartString(fullDate, options.includeSeconds),
|
|
39
|
+
timezone: fullDate.timezone,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
exports.toSimplePartStrings = toSimplePartStrings;
|
|
43
|
+
/**
|
|
44
|
+
* Converts a date into a simple, unambiguous date string.
|
|
45
|
+
*
|
|
46
|
+
* CAUTION: this does not user locale setting and should therefore not be used for user-facing date
|
|
47
|
+
* formatting. Prefer using `toLocaleString` instead for user-facing strings.
|
|
48
|
+
*/
|
|
49
|
+
function toSimpleString(fullDate, options) {
|
|
50
|
+
const parts = toSimplePartStrings(fullDate, options);
|
|
51
|
+
const stringParts = [
|
|
52
|
+
parts.date,
|
|
53
|
+
parts.time,
|
|
54
|
+
options.includeTimezone && `(${parts.timezone})`,
|
|
55
|
+
].filter(common_1.isTruthy);
|
|
56
|
+
return stringParts.join(' ');
|
|
57
|
+
}
|
|
58
|
+
exports.toSimpleString = toSimpleString;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toIsoString = exports.toTimestamp = void 0;
|
|
4
|
+
const luxon_date_time_conversion_1 = require("../full-date/luxon-date-time-conversion");
|
|
5
|
+
const timezones_1 = require("../timezone/timezones");
|
|
6
|
+
/** Convert a FullDate into a unix timestamp with milliseconds. */
|
|
7
|
+
function toTimestamp(fullDate) {
|
|
8
|
+
return (0, luxon_date_time_conversion_1.toLuxonDateTime)(fullDate).toMillis();
|
|
9
|
+
}
|
|
10
|
+
exports.toTimestamp = toTimestamp;
|
|
11
|
+
/** Convert a FullDate into an ISO string in UTC; always ends in Z. */
|
|
12
|
+
function toIsoString(fullDate) {
|
|
13
|
+
const isoString = (0, luxon_date_time_conversion_1.toLuxonDateTime)(fullDate).setZone(timezones_1.utcTimezone).toISO();
|
|
14
|
+
/** Ignore this edge case in the types and idk how to trigger it. */
|
|
15
|
+
/* c8 ignore next 3 */
|
|
16
|
+
if (!isoString) {
|
|
17
|
+
throw new Error(`Unable to get ISO string for '${JSON.stringify(fullDate)}'`);
|
|
18
|
+
}
|
|
19
|
+
return isoString;
|
|
20
|
+
}
|
|
21
|
+
exports.toIsoString = toIsoString;
|
package/dist/cjs/index.js
CHANGED
|
@@ -19,9 +19,16 @@ __exportStar(require("./date-operations/combine-dates"), exports);
|
|
|
19
19
|
__exportStar(require("./date-operations/diff-dates"), exports);
|
|
20
20
|
__exportStar(require("./duration"), exports);
|
|
21
21
|
__exportStar(require("./extra-utils/date-transforms"), exports);
|
|
22
|
+
__exportStar(require("./extra-utils/has-date-props"), exports);
|
|
22
23
|
__exportStar(require("./extra-utils/js-date-conversion"), exports);
|
|
23
24
|
__exportStar(require("./extra-utils/now"), exports);
|
|
24
25
|
__exportStar(require("./extra-utils/zero"), exports);
|
|
26
|
+
__exportStar(require("./formatting/formatted-string"), exports);
|
|
27
|
+
__exportStar(require("./formatting/html-input"), exports);
|
|
28
|
+
__exportStar(require("./formatting/relative-string"), exports);
|
|
29
|
+
__exportStar(require("./formatting/simple-strings"), exports);
|
|
30
|
+
__exportStar(require("./formatting/string-format-types"), exports);
|
|
31
|
+
__exportStar(require("./formatting/timestamp"), exports);
|
|
25
32
|
__exportStar(require("./full-date/create-full-date"), exports);
|
|
26
33
|
__exportStar(require("./full-date/date-like"), exports);
|
|
27
34
|
__exportStar(require("./full-date/format-presets"), exports);
|
|
@@ -29,8 +36,6 @@ __exportStar(require("./full-date/full-date-shape"), exports);
|
|
|
29
36
|
__exportStar(require("./full-date/is-valid-full-date"), exports);
|
|
30
37
|
__exportStar(require("./full-date/luxon-date-time-conversion"), exports);
|
|
31
38
|
__exportStar(require("./full-date/parsing"), exports);
|
|
32
|
-
__exportStar(require("./full-date/primitive-conversions"), exports);
|
|
33
|
-
__exportStar(require("./full-date/string-format-types"), exports);
|
|
34
39
|
__exportStar(require("./locales"), exports);
|
|
35
40
|
__exportStar(require("./timezone/timezone-checks"), exports);
|
|
36
41
|
__exportStar(require("./timezone/timezone-names"), exports);
|
|
@@ -1,29 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Duration } from '../duration';
|
|
1
|
+
import { AllDurations, Duration, DurationUnit } from '../duration';
|
|
3
2
|
import { FullDate } from '../full-date/full-date-shape';
|
|
4
|
-
export type MaybeTuple<T> = T | AtLeastTuple<T, 1>;
|
|
5
3
|
/**
|
|
6
|
-
*
|
|
7
|
-
* causing inaccuracies and many issues. See
|
|
8
|
-
* https://moment.github.io/luxon/#/math?id=casual-vs-longterm-conversion-accuracy for more info.
|
|
4
|
+
* Diffs two dates and returns the diff in the specific unit.
|
|
9
5
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
6
|
+
* Note: when years, quarters, or months are used for the unit then "long term" durations are used
|
|
7
|
+
* to calculate the diff. See more details here:
|
|
8
|
+
* https://moment.github.io/luxon/#/math?id=casual-vs-longterm-conversion-accuracy
|
|
12
9
|
*/
|
|
13
|
-
export declare
|
|
14
|
-
Weeks = "weeks",
|
|
15
|
-
Days = "days",
|
|
16
|
-
Hours = "hours",
|
|
17
|
-
Minutes = "minutes",
|
|
18
|
-
Seconds = "seconds",
|
|
19
|
-
Milliseconds = "milliseconds"
|
|
20
|
-
}
|
|
21
|
-
export declare function diffDates<const DurationKeys extends MaybeTuple<DiffUnit> = MaybeTuple<DiffUnit>>({ start, end, unit, }: {
|
|
10
|
+
export declare function diffDates<const ChosenDurationKey extends DurationUnit>({ start, end, unit, }: {
|
|
22
11
|
start: FullDate;
|
|
23
12
|
end: FullDate;
|
|
24
|
-
unit:
|
|
25
|
-
}): Duration<
|
|
26
|
-
|
|
13
|
+
unit: ChosenDurationKey;
|
|
14
|
+
}): Duration<ChosenDurationKey>;
|
|
15
|
+
/**
|
|
16
|
+
* Diffs two dates and returns that diff in each unit. Note that the unit in the returned object are
|
|
17
|
+
* not meant to be added together, each unit is instead the same value but calculated in that given
|
|
18
|
+
* unit.
|
|
19
|
+
*
|
|
20
|
+
* Note: when years, quarters, or months are used for the unit then "long term" durations are used
|
|
21
|
+
* to calculate the diff. See more details here:
|
|
22
|
+
* https://moment.github.io/luxon/#/math?id=casual-vs-longterm-conversion-accuracy
|
|
23
|
+
*/
|
|
24
|
+
export declare function diffDatesAllUnits({ start, end }: {
|
|
27
25
|
start: FullDate;
|
|
28
26
|
end: FullDate;
|
|
27
|
+
}): AllDurations;
|
|
28
|
+
export declare function isDateAfter({ relativeTo, fullDate, }: {
|
|
29
|
+
relativeTo: FullDate;
|
|
30
|
+
fullDate: FullDate;
|
|
29
31
|
}): boolean;
|
|
@@ -1,27 +1,65 @@
|
|
|
1
|
+
import { typedObjectFromEntries } from '@augment-vir/common';
|
|
2
|
+
import { DurationUnit, orderedDurationUnits } from '../duration';
|
|
1
3
|
import { toLuxonDateTime } from '../full-date/luxon-date-time-conversion';
|
|
4
|
+
const conversionAccuracies = {
|
|
5
|
+
[DurationUnit.Years]: 'longterm',
|
|
6
|
+
[DurationUnit.Quarters]: 'longterm',
|
|
7
|
+
[DurationUnit.Months]: 'longterm',
|
|
8
|
+
[DurationUnit.Weeks]: 'casual',
|
|
9
|
+
[DurationUnit.Days]: 'casual',
|
|
10
|
+
[DurationUnit.Hours]: 'casual',
|
|
11
|
+
[DurationUnit.Minutes]: 'casual',
|
|
12
|
+
[DurationUnit.Seconds]: 'casual',
|
|
13
|
+
[DurationUnit.Milliseconds]: 'casual',
|
|
14
|
+
};
|
|
2
15
|
/**
|
|
3
|
-
*
|
|
4
|
-
* causing inaccuracies and many issues. See
|
|
5
|
-
* https://moment.github.io/luxon/#/math?id=casual-vs-longterm-conversion-accuracy for more info.
|
|
16
|
+
* Diffs two dates and returns the diff in the specific unit.
|
|
6
17
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
18
|
+
* Note: when years, quarters, or months are used for the unit then "long term" durations are used
|
|
19
|
+
* to calculate the diff. See more details here:
|
|
20
|
+
* https://moment.github.io/luxon/#/math?id=casual-vs-longterm-conversion-accuracy
|
|
9
21
|
*/
|
|
10
|
-
export var DiffUnit;
|
|
11
|
-
(function (DiffUnit) {
|
|
12
|
-
DiffUnit["Weeks"] = "weeks";
|
|
13
|
-
DiffUnit["Days"] = "days";
|
|
14
|
-
DiffUnit["Hours"] = "hours";
|
|
15
|
-
DiffUnit["Minutes"] = "minutes";
|
|
16
|
-
DiffUnit["Seconds"] = "seconds";
|
|
17
|
-
DiffUnit["Milliseconds"] = "milliseconds";
|
|
18
|
-
})(DiffUnit || (DiffUnit = {}));
|
|
19
22
|
export function diffDates({ start, end, unit, }) {
|
|
20
23
|
const luxonDateStart = toLuxonDateTime(start);
|
|
21
24
|
const luxonDateEnd = toLuxonDateTime(end);
|
|
22
|
-
const diff = luxonDateEnd
|
|
25
|
+
const diff = luxonDateEnd
|
|
26
|
+
.diff(luxonDateStart, unit, {
|
|
27
|
+
conversionAccuracy: conversionAccuracies[unit],
|
|
28
|
+
})
|
|
29
|
+
.toObject();
|
|
23
30
|
return diff;
|
|
24
31
|
}
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Diffs two dates and returns that diff in each unit. Note that the unit in the returned object are
|
|
34
|
+
* not meant to be added together, each unit is instead the same value but calculated in that given
|
|
35
|
+
* unit.
|
|
36
|
+
*
|
|
37
|
+
* Note: when years, quarters, or months are used for the unit then "long term" durations are used
|
|
38
|
+
* to calculate the diff. See more details here:
|
|
39
|
+
* https://moment.github.io/luxon/#/math?id=casual-vs-longterm-conversion-accuracy
|
|
40
|
+
*/
|
|
41
|
+
export function diffDatesAllUnits({ start, end }) {
|
|
42
|
+
const allUnitDiffEntries = orderedDurationUnits.map((durationUnit) => {
|
|
43
|
+
const diff = diffDates({
|
|
44
|
+
start,
|
|
45
|
+
end,
|
|
46
|
+
unit: durationUnit,
|
|
47
|
+
});
|
|
48
|
+
const duration = diff[durationUnit];
|
|
49
|
+
/** Ignore this edge case in coverage cause its for type guarding. */
|
|
50
|
+
/* c8 ignore next 5 */
|
|
51
|
+
if (duration == undefined) {
|
|
52
|
+
throw new Error(`Internal date-vir error: failed to find duration for '${durationUnit}'`);
|
|
53
|
+
}
|
|
54
|
+
return [
|
|
55
|
+
durationUnit,
|
|
56
|
+
duration,
|
|
57
|
+
];
|
|
58
|
+
});
|
|
59
|
+
const allDurations = typedObjectFromEntries(allUnitDiffEntries);
|
|
60
|
+
return allDurations;
|
|
61
|
+
}
|
|
62
|
+
export function isDateAfter({ relativeTo, fullDate, }) {
|
|
63
|
+
return (diffDates({ start: relativeTo, end: fullDate, unit: DurationUnit.Milliseconds })
|
|
64
|
+
.milliseconds >= 0);
|
|
27
65
|
}
|
package/dist/esm/duration.d.ts
CHANGED
|
@@ -1,11 +1,55 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { RequiredAndNotNull } from '@augment-vir/common';
|
|
2
|
+
export declare enum DurationUnit {
|
|
3
|
+
Years = "years",
|
|
4
|
+
Quarters = "quarters",
|
|
5
|
+
Months = "months",
|
|
6
|
+
Weeks = "weeks",
|
|
7
|
+
Days = "days",
|
|
8
|
+
Hours = "hours",
|
|
9
|
+
Minutes = "minutes",
|
|
10
|
+
Seconds = "seconds",
|
|
11
|
+
Milliseconds = "milliseconds"
|
|
12
|
+
}
|
|
13
|
+
export declare const singularDurationUnitNames: {
|
|
14
|
+
readonly milliseconds: "millisecond";
|
|
15
|
+
readonly seconds: "second";
|
|
16
|
+
readonly minutes: "minute";
|
|
17
|
+
readonly hours: "hour";
|
|
18
|
+
readonly days: "day";
|
|
19
|
+
readonly weeks: "week";
|
|
20
|
+
readonly months: "month";
|
|
21
|
+
readonly quarters: "quarter";
|
|
22
|
+
readonly years: "year";
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Array of DurationUnit values: from smallest unit (milliseconds at index 0) to longest unit
|
|
26
|
+
* (years).
|
|
27
|
+
*/
|
|
28
|
+
export declare const orderedDurationUnits: readonly [DurationUnit.Milliseconds, DurationUnit.Seconds, DurationUnit.Minutes, DurationUnit.Hours, DurationUnit.Days, DurationUnit.Weeks, DurationUnit.Months, DurationUnit.Quarters, DurationUnit.Years];
|
|
29
|
+
/**
|
|
30
|
+
* All possible options for the more strict Duration type. Matches the DurationObjectUnits type from
|
|
31
|
+
* the luxon package.
|
|
32
|
+
*/
|
|
33
|
+
export type AnyDuration = {
|
|
34
|
+
years?: number | undefined;
|
|
35
|
+
quarters?: number | undefined;
|
|
36
|
+
months?: number | undefined;
|
|
37
|
+
weeks?: number | undefined;
|
|
38
|
+
days?: number | undefined;
|
|
39
|
+
hours?: number | undefined;
|
|
40
|
+
minutes?: number | undefined;
|
|
41
|
+
seconds?: number | undefined;
|
|
42
|
+
milliseconds?: number | undefined;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* All possible duration units at once. Whether these duration units should be added together to
|
|
46
|
+
* form the whole picture or whether each duration is the same value but calculated in different
|
|
47
|
+
* units depends on the context of this type's usage.
|
|
48
|
+
*/
|
|
49
|
+
export type AllDurations = RequiredAndNotNull<AnyDuration>;
|
|
6
50
|
/**
|
|
7
51
|
* Not a single date instance, but a description of a date duration. Used to calculate diffs between
|
|
8
52
|
* dates, or add offsets to an existing date, or describe a single time duration. Usually only one
|
|
9
53
|
* property is set on this at any given time.
|
|
10
54
|
*/
|
|
11
|
-
export type Duration<DurationKeys extends
|
|
55
|
+
export type Duration<DurationKeys extends DurationUnit = DurationUnit> = DurationUnit extends DurationKeys ? AnyDuration : Pick<AllDurations, `${DurationKeys}`>;
|