date-vir 5.3.1 → 6.0.1
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/LICENSE-MIT +1 -1
- package/README.md +28 -28
- package/dist/date-operations/calculate-relative-date.d.ts +17 -0
- package/dist/{esm/date-operations → date-operations}/calculate-relative-date.js +10 -1
- package/dist/date-operations/combine-dates.d.ts +43 -0
- package/dist/{esm/date-operations → date-operations}/combine-dates.js +6 -4
- package/dist/date-operations/diff-dates.d.ts +95 -0
- package/dist/date-operations/diff-dates.js +124 -0
- package/dist/extra-utils/has-date-props.d.ts +35 -0
- package/dist/extra-utils/has-date-props.js +46 -0
- package/dist/extra-utils/js-date-conversion.d.ts +26 -0
- package/dist/extra-utils/js-date-conversion.js +28 -0
- package/dist/extra-utils/now.d.ts +56 -0
- package/dist/extra-utils/now.js +68 -0
- package/dist/extra-utils/override-date.d.ts +27 -0
- package/dist/extra-utils/override-date.js +27 -0
- package/dist/extra-utils/zero.d.ts +99 -0
- package/dist/extra-utils/zero.js +94 -0
- package/dist/formatting/formatted-string.d.ts +58 -0
- package/dist/formatting/formatted-string.js +73 -0
- package/dist/formatting/html-input.d.ts +30 -0
- package/dist/formatting/html-input.js +47 -0
- package/dist/formatting/relative-string.d.ts +53 -0
- package/dist/formatting/relative-string.js +93 -0
- package/dist/formatting/simple-strings.d.ts +187 -0
- package/dist/formatting/simple-strings.js +120 -0
- package/dist/formatting/string-format-types.d.ts +59 -0
- package/dist/formatting/string-format-types.js +19 -0
- package/dist/formatting/timestamp.d.ts +51 -0
- package/dist/formatting/timestamp.js +61 -0
- package/dist/full-date/create-full-date.d.ts +91 -0
- package/dist/full-date/create-full-date.js +142 -0
- package/dist/full-date/date-like.d.ts +9 -0
- package/dist/{esm/full-date → full-date}/format-presets.d.ts +4 -2
- package/dist/{esm/full-date → full-date}/format-presets.js +4 -2
- package/dist/full-date/full-date-parts.d.ts +48 -0
- package/dist/full-date/full-date-parts.js +45 -0
- package/dist/full-date/full-date-shape.d.ts +106 -0
- package/dist/{esm/full-date → full-date}/full-date-shape.js +15 -22
- package/dist/full-date/is-valid-full-date.d.ts +21 -0
- package/dist/full-date/is-valid-full-date.js +38 -0
- package/dist/full-date/luxon-date-time-conversion.d.ts +19 -0
- package/dist/{esm/full-date → full-date}/luxon-date-time-conversion.js +10 -6
- package/dist/full-date/parsing.d.ts +33 -0
- package/dist/full-date/parsing.js +47 -0
- package/dist/full-date/string-parsing.d.ts +9 -0
- package/dist/{esm/full-date → full-date}/string-parsing.js +6 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +27 -0
- package/dist/locales.d.ts +6 -0
- package/dist/locales.js +7 -0
- package/dist/timezone/timezone-checks.d.ts +21 -0
- package/dist/timezone/timezone-checks.js +34 -0
- package/dist/{esm/timezone → timezone}/timezone-names.d.ts +11 -5
- package/dist/{esm/timezone → timezone}/timezone-names.js +11 -3
- package/dist/timezone/timezones.d.ts +42 -0
- package/dist/timezone/timezones.js +31 -0
- package/package.json +30 -48
- package/cspell.config.cjs +0 -13
- package/dist/cjs/date-operations/calculate-relative-date.js +0 -12
- package/dist/cjs/date-operations/combine-dates.js +0 -50
- package/dist/cjs/date-operations/diff-dates.js +0 -105
- package/dist/cjs/duration/duration-unit.js +0 -41
- package/dist/cjs/duration/duration-utils.js +0 -42
- package/dist/cjs/duration/duration.js +0 -2
- package/dist/cjs/extra-utils/date-transforms.js +0 -8
- package/dist/cjs/extra-utils/has-date-props.js +0 -25
- package/dist/cjs/extra-utils/js-date-conversion.js +0 -8
- package/dist/cjs/extra-utils/now.js +0 -22
- package/dist/cjs/extra-utils/zero.js +0 -31
- package/dist/cjs/formatting/formatted-string.js +0 -34
- package/dist/cjs/formatting/html-input.js +0 -37
- package/dist/cjs/formatting/relative-string.js +0 -77
- package/dist/cjs/formatting/simple-strings.js +0 -58
- package/dist/cjs/formatting/string-format-types.js +0 -9
- package/dist/cjs/formatting/timestamp.js +0 -21
- package/dist/cjs/full-date/create-full-date.js +0 -81
- package/dist/cjs/full-date/date-like.js +0 -2
- package/dist/cjs/full-date/format-presets.js +0 -32
- package/dist/cjs/full-date/full-date-shape.js +0 -54
- package/dist/cjs/full-date/is-valid-full-date.js +0 -28
- package/dist/cjs/full-date/luxon-date-time-conversion.js +0 -43
- package/dist/cjs/full-date/parsing.js +0 -48
- package/dist/cjs/full-date/string-parsing.js +0 -33
- package/dist/cjs/index.js +0 -44
- package/dist/cjs/locales.js +0 -5
- package/dist/cjs/timezone/timezone-checks.js +0 -34
- package/dist/cjs/timezone/timezone-names.js +0 -479
- package/dist/cjs/timezone/timezones.js +0 -14
- package/dist/esm/date-operations/calculate-relative-date.d.ts +0 -8
- package/dist/esm/date-operations/combine-dates.d.ts +0 -35
- package/dist/esm/date-operations/diff-dates.d.ts +0 -66
- package/dist/esm/date-operations/diff-dates.js +0 -100
- package/dist/esm/duration/duration-unit.d.ts +0 -27
- package/dist/esm/duration/duration-unit.js +0 -38
- package/dist/esm/duration/duration-utils.d.ts +0 -11
- package/dist/esm/duration/duration-utils.js +0 -37
- package/dist/esm/duration/duration.d.ts +0 -32
- package/dist/esm/duration/duration.js +0 -1
- package/dist/esm/extra-utils/date-transforms.d.ts +0 -4
- package/dist/esm/extra-utils/date-transforms.js +0 -4
- package/dist/esm/extra-utils/has-date-props.d.ts +0 -9
- package/dist/esm/extra-utils/has-date-props.js +0 -20
- package/dist/esm/extra-utils/js-date-conversion.d.ts +0 -2
- package/dist/esm/extra-utils/js-date-conversion.js +0 -4
- package/dist/esm/extra-utils/now.d.ts +0 -5
- package/dist/esm/extra-utils/now.js +0 -16
- package/dist/esm/extra-utils/zero.d.ts +0 -31
- package/dist/esm/extra-utils/zero.js +0 -26
- package/dist/esm/formatting/formatted-string.d.ts +0 -14
- package/dist/esm/formatting/formatted-string.js +0 -29
- package/dist/esm/formatting/html-input.d.ts +0 -19
- package/dist/esm/formatting/html-input.js +0 -33
- package/dist/esm/formatting/relative-string.d.ts +0 -31
- package/dist/esm/formatting/relative-string.js +0 -73
- package/dist/esm/formatting/simple-strings.d.ts +0 -71
- package/dist/esm/formatting/simple-strings.js +0 -51
- package/dist/esm/formatting/string-format-types.d.ts +0 -7
- package/dist/esm/formatting/string-format-types.js +0 -5
- package/dist/esm/formatting/timestamp.d.ts +0 -6
- package/dist/esm/formatting/timestamp.js +0 -16
- package/dist/esm/full-date/create-full-date.d.ts +0 -21
- package/dist/esm/full-date/create-full-date.js +0 -73
- package/dist/esm/full-date/date-like.d.ts +0 -5
- package/dist/esm/full-date/full-date-shape.d.ts +0 -80
- package/dist/esm/full-date/is-valid-full-date.d.ts +0 -5
- package/dist/esm/full-date/is-valid-full-date.js +0 -22
- package/dist/esm/full-date/luxon-date-time-conversion.d.ts +0 -15
- package/dist/esm/full-date/parsing.d.ts +0 -27
- package/dist/esm/full-date/parsing.js +0 -43
- package/dist/esm/full-date/string-parsing.d.ts +0 -3
- package/dist/esm/index.d.ts +0 -28
- package/dist/esm/index.js +0 -28
- package/dist/esm/locales.d.ts +0 -1
- package/dist/esm/locales.js +0 -2
- package/dist/esm/timezone/timezone-checks.d.ts +0 -17
- package/dist/esm/timezone/timezone-checks.js +0 -29
- package/dist/esm/timezone/timezones.d.ts +0 -480
- package/dist/esm/timezone/timezones.js +0 -11
- package/public/index.css +0 -7
- /package/dist/{esm/full-date → full-date}/date-like.js +0 -0
package/LICENSE-MIT
CHANGED
package/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Easy dates and times with explicit timezones (and typed timezones).
|
|
4
4
|
|
|
5
|
-
`date-vir` revolves around the new `FullDate` type, which includes all the information you need to correctly pinpoint _and_ format a given point in time. Most notably, `FullDate` always includes a `timezone` property, so you _always_ know what timezone the date was originally defined in, or what timezone the date is intended to be used in:
|
|
6
|
-
|
|
7
5
|
Full docs: http://electrovir.github.io/date-vir
|
|
8
6
|
|
|
7
|
+
`date-vir` revolves around its [`FullDate`](http://electrovir.github.io/date-vir/types/FullDate.html) type. `FullDate` includes all the information you need to correctly pinpoint _and_ format a given point in time. Most notably, `FullDate` always includes a `timezone` property, so you _always_ know what timezone the date was originally defined in, or what timezone the date is intended to be used in:
|
|
8
|
+
|
|
9
9
|
<!-- example-link: src/readme-examples/full-date.example.ts -->
|
|
10
10
|
|
|
11
11
|
```TypeScript
|
|
12
|
-
import {FullDate,
|
|
12
|
+
import {FullDate, utcTimezone} from 'date-vir';
|
|
13
13
|
|
|
14
14
|
const myDate: FullDate = {
|
|
15
15
|
year: 2023,
|
|
@@ -21,13 +21,13 @@ const myDate: FullDate = {
|
|
|
21
21
|
second: 27,
|
|
22
22
|
millisecond: 652,
|
|
23
23
|
|
|
24
|
-
timezone:
|
|
24
|
+
timezone: utcTimezone,
|
|
25
25
|
};
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
## Creating a FullDate
|
|
29
29
|
|
|
30
|
-
Several functions are available for creating `FullDate` objects
|
|
30
|
+
Several functions are available for creating `FullDate` objects:
|
|
31
31
|
|
|
32
32
|
<!-- example-link: src/readme-examples/full-date-creation.example.ts -->
|
|
33
33
|
|
|
@@ -35,26 +35,26 @@ Several functions are available for creating `FullDate` objects, with `createFul
|
|
|
35
35
|
import {
|
|
36
36
|
createFullDate,
|
|
37
37
|
getNowFullDate,
|
|
38
|
+
parseDateStringWithPattern,
|
|
38
39
|
parseInputElementValue,
|
|
39
|
-
|
|
40
|
-
timezones,
|
|
40
|
+
Timezone,
|
|
41
41
|
} from 'date-vir';
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* Creates a FullDate from a wide range of possible inputs. See TypeScript types for full details on
|
|
45
45
|
* available inputs.
|
|
46
46
|
*/
|
|
47
|
-
createFullDate('2023-06-05',
|
|
47
|
+
createFullDate('2023-06-05', Timezone['Europe/Rome']);
|
|
48
48
|
|
|
49
49
|
/** Get the current date and time right now in the given timezone. */
|
|
50
|
-
getNowFullDate(
|
|
50
|
+
getNowFullDate(Timezone['America/Argentina/Buenos_Aires']);
|
|
51
51
|
|
|
52
52
|
/**
|
|
53
53
|
* Parsed the value of an <input> element directly from the element itself. This is intended to be
|
|
54
54
|
* used for type="date" or type="time" <input> elements, but any input element with a valid date or
|
|
55
55
|
* time string will work.
|
|
56
56
|
*/
|
|
57
|
-
parseInputElementValue(document.querySelector('input'),
|
|
57
|
+
parseInputElementValue(document.querySelector('input'), Timezone['Asia/Tokyo']);
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
60
|
* If you have a really oddly formatted date/time string and createFullDate does not suffice, you
|
|
@@ -62,14 +62,14 @@ parseInputElementValue(document.querySelector('input'), timezones['Asia/Tokyo'])
|
|
|
62
62
|
* so you can see all the formatString options in its docs:
|
|
63
63
|
* https://moment.github.io/luxon/#/parsing?id=table-of-tokens
|
|
64
64
|
*/
|
|
65
|
-
|
|
65
|
+
parseDateStringWithPattern({
|
|
66
66
|
dateString: '870-0-14-19 5 2023 6',
|
|
67
67
|
formatString: 'S-s-h-m d yyyy M',
|
|
68
|
-
timezone:
|
|
68
|
+
timezone: Timezone['America/Cancun'],
|
|
69
69
|
});
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
## Outputs
|
|
73
73
|
|
|
74
74
|
`FullDate` objects are easily converted into other formats (usually strings) with the included functions:
|
|
75
75
|
|
|
@@ -77,17 +77,17 @@ parseStrangeString({
|
|
|
77
77
|
|
|
78
78
|
```TypeScript
|
|
79
79
|
import {
|
|
80
|
-
FullDatePartEnum,
|
|
81
80
|
createFullDate,
|
|
82
81
|
formatPresets,
|
|
83
|
-
|
|
82
|
+
FullDatePart,
|
|
83
|
+
Timezone,
|
|
84
84
|
toHtmlInputString,
|
|
85
|
-
toIsoString,
|
|
86
85
|
toLocaleString,
|
|
87
86
|
toTimestamp,
|
|
87
|
+
toUtcIsoString,
|
|
88
88
|
} from 'date-vir';
|
|
89
89
|
|
|
90
|
-
const myFullDate = createFullDate('2023-06-05T14:19:00.870Z',
|
|
90
|
+
const myFullDate = createFullDate('2023-06-05T14:19:00.870Z', Timezone['America/Chicago']);
|
|
91
91
|
|
|
92
92
|
/**
|
|
93
93
|
* Converts the given FullDate into a UTC unix timestamp with milliseconds. Since the output is a
|
|
@@ -101,7 +101,7 @@ toTimestamp(myFullDate); // returns 1685974740870
|
|
|
101
101
|
* FullDate object is shifted to a different timezone, the output of this function will be the
|
|
102
102
|
* same.
|
|
103
103
|
*/
|
|
104
|
-
|
|
104
|
+
toUtcIsoString(myFullDate); // returns '2023-06-05T14:19:00.870Z'
|
|
105
105
|
|
|
106
106
|
/**
|
|
107
107
|
* Converts the given FullDate to a locale-based formatted string. The second argument, the options
|
|
@@ -113,21 +113,21 @@ toLocaleString(myFullDate, formatPresets.DatetimeFull); // returns 'June 5, 2023
|
|
|
113
113
|
* Formats the given FullDate to a string so that it is ready to be assigned to the value attribute
|
|
114
114
|
* of an <input type="date" /> element.
|
|
115
115
|
*/
|
|
116
|
-
toHtmlInputString(myFullDate,
|
|
116
|
+
toHtmlInputString(myFullDate, FullDatePart.Date); // returns '2023-06-05'
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
## Timezone
|
|
120
120
|
|
|
121
121
|
`date-vir` exposes a type-safe list of timezone names, including shortcuts for the user's timezone and the UTC timezone:
|
|
122
122
|
|
|
123
123
|
<!-- example-link: src/readme-examples/timezones.example.ts -->
|
|
124
124
|
|
|
125
125
|
```TypeScript
|
|
126
|
-
import {
|
|
126
|
+
import {Timezone, userTimezone, utcTimezone} from 'date-vir';
|
|
127
127
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
Timezone['Africa/Abidjan'];
|
|
129
|
+
Timezone['America/Los_Angeles'];
|
|
130
|
+
Timezone['Etc/GMT+1'];
|
|
131
131
|
|
|
132
132
|
utcTimezone;
|
|
133
133
|
userTimezone;
|
|
@@ -135,16 +135,16 @@ userTimezone;
|
|
|
135
135
|
|
|
136
136
|
Note that the current list of timezone names included in this package was generated from Firefox 106.0.2.
|
|
137
137
|
|
|
138
|
-
|
|
138
|
+
## Luxon
|
|
139
139
|
|
|
140
140
|
The parsing and timezone conversions in `date-vir` utilize the [`luxon`](https://www.npmjs.com/luxon) package under the hood. If you wish to gain full `luxon` control over a `FullDate` object, `date-vir` provides an easy conversion function:
|
|
141
141
|
|
|
142
142
|
<!-- example-link: src/readme-examples/luxon-conversion.example.ts -->
|
|
143
143
|
|
|
144
144
|
```TypeScript
|
|
145
|
-
import {createFullDate,
|
|
145
|
+
import {createFullDate, Timezone, toLuxonDateTime} from 'date-vir';
|
|
146
146
|
|
|
147
|
-
const myFullDate = createFullDate('2023-06-05T14:19:00.870Z',
|
|
147
|
+
const myFullDate = createFullDate('2023-06-05T14:19:00.870Z', Timezone['America/Chicago']);
|
|
148
148
|
|
|
149
149
|
toLuxonDateTime(myFullDate);
|
|
150
150
|
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AnyDuration } from '@date-vir/duration';
|
|
2
|
+
import { FullDate } from '../full-date/full-date-shape.js';
|
|
3
|
+
import { Timezone } from '../timezone/timezones.js';
|
|
4
|
+
/**
|
|
5
|
+
* Calculates a new date starting at the given fullDate and adding the given offsets. Offsets can be
|
|
6
|
+
* negative to go backwards in time.
|
|
7
|
+
*
|
|
8
|
+
* @category Calculation
|
|
9
|
+
* @example
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* import {calculateRelativeDate} from 'date-vir';
|
|
13
|
+
*
|
|
14
|
+
* calculateRelativeDate(getNowInUserTimezone(), {days: 2});
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function calculateRelativeDate<const SpecificTimezone extends Timezone>(fullDate: Readonly<FullDate<SpecificTimezone>>, offset: Readonly<AnyDuration>): FullDate<SpecificTimezone>;
|
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
import { parseLuxonDateTime, toLuxonDateTime } from '../full-date/luxon-date-time-conversion';
|
|
1
|
+
import { parseLuxonDateTime, toLuxonDateTime } from '../full-date/luxon-date-time-conversion.js';
|
|
2
2
|
/**
|
|
3
3
|
* Calculates a new date starting at the given fullDate and adding the given offsets. Offsets can be
|
|
4
4
|
* negative to go backwards in time.
|
|
5
|
+
*
|
|
6
|
+
* @category Calculation
|
|
7
|
+
* @example
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* import {calculateRelativeDate} from 'date-vir';
|
|
11
|
+
*
|
|
12
|
+
* calculateRelativeDate(getNowInUserTimezone(), {days: 2});
|
|
13
|
+
* ```
|
|
5
14
|
*/
|
|
6
15
|
export function calculateRelativeDate(fullDate, offset) {
|
|
7
16
|
return parseLuxonDateTime(toLuxonDateTime(fullDate).plus(offset));
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { FullDatePart } from '../full-date/full-date-parts.js';
|
|
2
|
+
import { DatePart, FullDate, TimePart } from '../full-date/full-date-shape.js';
|
|
3
|
+
import type { Timezone } from '../timezone/timezones.js';
|
|
4
|
+
/**
|
|
5
|
+
* An object containing date and/or time parts or neither. Used for {@link combineDateParts}
|
|
6
|
+
*
|
|
7
|
+
* @category Internal
|
|
8
|
+
*/
|
|
9
|
+
export type MaybeDateParts<SpecificTimezone extends Timezone> = Partial<{
|
|
10
|
+
[FullDatePart.Date]: DatePart<SpecificTimezone> | undefined | Partial<FullDate<SpecificTimezone>>;
|
|
11
|
+
[FullDatePart.Time]: TimePart<SpecificTimezone> | undefined | Partial<FullDate<SpecificTimezone>>;
|
|
12
|
+
}>;
|
|
13
|
+
/**
|
|
14
|
+
* A full date, time or date parts of a date, or undefined. Used for {@link combineDateParts}.
|
|
15
|
+
*
|
|
16
|
+
* @category Internal
|
|
17
|
+
*/
|
|
18
|
+
export type MaybeDatePart<SpecificTimezone extends Timezone> = FullDate<SpecificTimezone> | Partial<FullDate<SpecificTimezone>> | DatePart<SpecificTimezone> | TimePart<SpecificTimezone> | undefined;
|
|
19
|
+
export declare function combineDateParts<const SpecificTimezone extends Timezone>(maybeDateParts: {
|
|
20
|
+
[FullDatePart.Date]: DatePart<SpecificTimezone>;
|
|
21
|
+
[FullDatePart.Time]: TimePart<SpecificTimezone>;
|
|
22
|
+
}): FullDate<SpecificTimezone>;
|
|
23
|
+
export declare function combineDateParts(maybeDateParts: {
|
|
24
|
+
[FullDatePart.Date]?: undefined;
|
|
25
|
+
[FullDatePart.Time]?: undefined;
|
|
26
|
+
}): undefined;
|
|
27
|
+
export declare function combineDateParts<const SpecificTimezone extends Timezone>(maybeDateParts: {
|
|
28
|
+
[FullDatePart.Date]: DatePart<SpecificTimezone>;
|
|
29
|
+
[FullDatePart.Time]?: undefined;
|
|
30
|
+
}): DatePart<SpecificTimezone>;
|
|
31
|
+
export declare function combineDateParts<const SpecificTimezone extends Timezone>(maybeDateParts: {
|
|
32
|
+
[FullDatePart.Date]: DatePart<SpecificTimezone>;
|
|
33
|
+
[FullDatePart.Time]?: TimePart<SpecificTimezone> | undefined | Partial<FullDate<SpecificTimezone>>;
|
|
34
|
+
}): FullDate<SpecificTimezone> | DatePart<SpecificTimezone>;
|
|
35
|
+
export declare function combineDateParts<const SpecificTimezone extends Timezone>(maybeDateParts: {
|
|
36
|
+
[FullDatePart.Date]?: undefined;
|
|
37
|
+
[FullDatePart.Time]: TimePart<SpecificTimezone>;
|
|
38
|
+
}): TimePart<SpecificTimezone>;
|
|
39
|
+
export declare function combineDateParts<const SpecificTimezone extends Timezone>(maybeDateParts: {
|
|
40
|
+
[FullDatePart.Date]?: DatePart<SpecificTimezone> | undefined | Partial<FullDate<SpecificTimezone>>;
|
|
41
|
+
[FullDatePart.Time]: TimePart<SpecificTimezone>;
|
|
42
|
+
}): FullDate<SpecificTimezone> | TimePart<SpecificTimezone>;
|
|
43
|
+
export declare function combineDateParts<const SpecificTimezone extends Timezone>(maybeDateParts: MaybeDateParts<SpecificTimezone>): MaybeDatePart<SpecificTimezone>;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { isValidShape } from 'object-shape-tester';
|
|
2
|
-
import {
|
|
2
|
+
import { datePartShape, timePartShape, } from '../full-date/full-date-shape.js';
|
|
3
3
|
/**
|
|
4
|
-
* Combine two parts of a FullDate objects into a filled-in FullDate. Note that the
|
|
5
|
-
* match for both inputs. If two complete FullDate objects are passed in, only
|
|
6
|
-
* of each is used.
|
|
4
|
+
* Combine two parts of a {@link FullDate} objects into a filled-in {@link FullDate}. Note that the
|
|
5
|
+
* timezones must match for both inputs. If two complete {@link FullDate} objects are passed in, only
|
|
6
|
+
* the respective parts of each is used.
|
|
7
|
+
*
|
|
8
|
+
* @category Util
|
|
7
9
|
*/
|
|
8
10
|
export function combineDateParts(maybeDateParts) {
|
|
9
11
|
const timePart = isValidShape(maybeDateParts.time, timePartShape, {
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { type DurationBySelection, type DurationUnitSelection, type RoundOptions } from '@date-vir/duration';
|
|
2
|
+
import { FullDate } from '../full-date/full-date-shape.js';
|
|
3
|
+
/**
|
|
4
|
+
* Diffs two dates and returns the diff in the specified unit or units. When a multiple units are
|
|
5
|
+
* provided with the `units` input property, an array is returned with the full diff duration
|
|
6
|
+
* contained in each entry in the requested unit.
|
|
7
|
+
*
|
|
8
|
+
* Note: when years, quarters, or months are used for the unit, "long term" durations are used to
|
|
9
|
+
* calculate the diff. See more details here:
|
|
10
|
+
* https://moment.github.io/luxon/#/math?id=casual-vs-longterm-conversion-accuracy
|
|
11
|
+
*
|
|
12
|
+
* @category Calculation
|
|
13
|
+
* @example
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* import {diffDates, DurationUnit} from 'date-vir';
|
|
17
|
+
*
|
|
18
|
+
* const exampleDate: FullDate = {
|
|
19
|
+
* year: 2024,
|
|
20
|
+
* month: 1,
|
|
21
|
+
* day: 5,
|
|
22
|
+
* hour: 1,
|
|
23
|
+
* minute: 1,
|
|
24
|
+
* second: 1,
|
|
25
|
+
* millisecond: 1,
|
|
26
|
+
* timezone: 'UTC',
|
|
27
|
+
* };
|
|
28
|
+
*
|
|
29
|
+
* // get the diff in days
|
|
30
|
+
* diffDates({start: exampleDate, end: {...exampleDate, day: 6}}, {days: true}); // {days: 1}
|
|
31
|
+
* // get the full diff separately in days and also years
|
|
32
|
+
* diffDates(
|
|
33
|
+
* {
|
|
34
|
+
* start: exampleDate,
|
|
35
|
+
* end: {
|
|
36
|
+
* ...exampleDate,
|
|
37
|
+
* day: exampleDate.day + 1,
|
|
38
|
+
* hour: exampleDate.hour + 3,
|
|
39
|
+
* },
|
|
40
|
+
* },
|
|
41
|
+
* {
|
|
42
|
+
* days: true,
|
|
43
|
+
* hours: true,
|
|
44
|
+
* },
|
|
45
|
+
* );
|
|
46
|
+
* // {days: 1, hours: 3}
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare function diffDates<const SelectedUnits extends Readonly<DurationUnitSelection>>({ start, end, }: Readonly<{
|
|
50
|
+
start: Readonly<FullDate>;
|
|
51
|
+
end: Readonly<FullDate>;
|
|
52
|
+
}>,
|
|
53
|
+
/** Which units the output should contain. */
|
|
54
|
+
units: SelectedUnits, options?: Readonly<RoundOptions>): DurationBySelection<SelectedUnits>;
|
|
55
|
+
/**
|
|
56
|
+
* Checks if `fullDate` is after `relativeTo`.
|
|
57
|
+
*
|
|
58
|
+
* @category Calculation
|
|
59
|
+
* @example
|
|
60
|
+
*
|
|
61
|
+
* ```ts
|
|
62
|
+
* import {isDateAfter, type FullDate} from 'date-vir';
|
|
63
|
+
*
|
|
64
|
+
* const exampleDate: FullDate = {
|
|
65
|
+
* year: 2024,
|
|
66
|
+
* month: 1,
|
|
67
|
+
* day: 5,
|
|
68
|
+
* hour: 1,
|
|
69
|
+
* minute: 1,
|
|
70
|
+
* second: 1,
|
|
71
|
+
* millisecond: 1,
|
|
72
|
+
* timezone: 'UTC',
|
|
73
|
+
* };
|
|
74
|
+
*
|
|
75
|
+
* isDateAfter({
|
|
76
|
+
* fullDate: exampleDate,
|
|
77
|
+
* relativeTo: {
|
|
78
|
+
* ...exampleDate,
|
|
79
|
+
* year: 1900,
|
|
80
|
+
* },
|
|
81
|
+
* }); // `true`
|
|
82
|
+
*
|
|
83
|
+
* isDateAfter({
|
|
84
|
+
* fullDate: exampleDate,
|
|
85
|
+
* relativeTo: {
|
|
86
|
+
* ...exampleDate,
|
|
87
|
+
* year: 3000,
|
|
88
|
+
* },
|
|
89
|
+
* }); // `false`
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export declare function isDateAfter({ relativeTo, fullDate, }: {
|
|
93
|
+
relativeTo: Readonly<FullDate>;
|
|
94
|
+
fullDate: Readonly<FullDate>;
|
|
95
|
+
}): boolean;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { DurationUnit, flattenUnitSelection, roundDuration, } from '@date-vir/duration';
|
|
2
|
+
import { toLuxonDateTime } from '../full-date/luxon-date-time-conversion.js';
|
|
3
|
+
const conversionAccuracies = {
|
|
4
|
+
[DurationUnit.Years]: 'longterm',
|
|
5
|
+
[DurationUnit.Quarters]: 'longterm',
|
|
6
|
+
[DurationUnit.Months]: 'longterm',
|
|
7
|
+
[DurationUnit.Weeks]: 'casual',
|
|
8
|
+
[DurationUnit.Days]: 'casual',
|
|
9
|
+
[DurationUnit.Hours]: 'casual',
|
|
10
|
+
[DurationUnit.Minutes]: 'casual',
|
|
11
|
+
[DurationUnit.Seconds]: 'casual',
|
|
12
|
+
[DurationUnit.Milliseconds]: 'casual',
|
|
13
|
+
};
|
|
14
|
+
function getHighestPriorityConversionAccuracy(units) {
|
|
15
|
+
if (units.some((unit) => conversionAccuracies[unit] === 'longterm')) {
|
|
16
|
+
return 'longterm';
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
return 'casual';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Diffs two dates and returns the diff in the specified unit or units. When a multiple units are
|
|
24
|
+
* provided with the `units` input property, an array is returned with the full diff duration
|
|
25
|
+
* contained in each entry in the requested unit.
|
|
26
|
+
*
|
|
27
|
+
* Note: when years, quarters, or months are used for the unit, "long term" durations are used to
|
|
28
|
+
* calculate the diff. See more details here:
|
|
29
|
+
* https://moment.github.io/luxon/#/math?id=casual-vs-longterm-conversion-accuracy
|
|
30
|
+
*
|
|
31
|
+
* @category Calculation
|
|
32
|
+
* @example
|
|
33
|
+
*
|
|
34
|
+
* ```ts
|
|
35
|
+
* import {diffDates, DurationUnit} from 'date-vir';
|
|
36
|
+
*
|
|
37
|
+
* const exampleDate: FullDate = {
|
|
38
|
+
* year: 2024,
|
|
39
|
+
* month: 1,
|
|
40
|
+
* day: 5,
|
|
41
|
+
* hour: 1,
|
|
42
|
+
* minute: 1,
|
|
43
|
+
* second: 1,
|
|
44
|
+
* millisecond: 1,
|
|
45
|
+
* timezone: 'UTC',
|
|
46
|
+
* };
|
|
47
|
+
*
|
|
48
|
+
* // get the diff in days
|
|
49
|
+
* diffDates({start: exampleDate, end: {...exampleDate, day: 6}}, {days: true}); // {days: 1}
|
|
50
|
+
* // get the full diff separately in days and also years
|
|
51
|
+
* diffDates(
|
|
52
|
+
* {
|
|
53
|
+
* start: exampleDate,
|
|
54
|
+
* end: {
|
|
55
|
+
* ...exampleDate,
|
|
56
|
+
* day: exampleDate.day + 1,
|
|
57
|
+
* hour: exampleDate.hour + 3,
|
|
58
|
+
* },
|
|
59
|
+
* },
|
|
60
|
+
* {
|
|
61
|
+
* days: true,
|
|
62
|
+
* hours: true,
|
|
63
|
+
* },
|
|
64
|
+
* );
|
|
65
|
+
* // {days: 1, hours: 3}
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export function diffDates({ start, end, },
|
|
69
|
+
/** Which units the output should contain. */
|
|
70
|
+
units, options = {}) {
|
|
71
|
+
const luxonDateStart = toLuxonDateTime(start);
|
|
72
|
+
const luxonDateEnd = toLuxonDateTime(end);
|
|
73
|
+
const selectedUnits = flattenUnitSelection(units);
|
|
74
|
+
const conversionAccuracy = getHighestPriorityConversionAccuracy(selectedUnits);
|
|
75
|
+
const additiveDiff = luxonDateEnd
|
|
76
|
+
.diff(luxonDateStart, selectedUnits, {
|
|
77
|
+
conversionAccuracy,
|
|
78
|
+
})
|
|
79
|
+
.toObject();
|
|
80
|
+
return roundDuration(additiveDiff, options);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Checks if `fullDate` is after `relativeTo`.
|
|
84
|
+
*
|
|
85
|
+
* @category Calculation
|
|
86
|
+
* @example
|
|
87
|
+
*
|
|
88
|
+
* ```ts
|
|
89
|
+
* import {isDateAfter, type FullDate} from 'date-vir';
|
|
90
|
+
*
|
|
91
|
+
* const exampleDate: FullDate = {
|
|
92
|
+
* year: 2024,
|
|
93
|
+
* month: 1,
|
|
94
|
+
* day: 5,
|
|
95
|
+
* hour: 1,
|
|
96
|
+
* minute: 1,
|
|
97
|
+
* second: 1,
|
|
98
|
+
* millisecond: 1,
|
|
99
|
+
* timezone: 'UTC',
|
|
100
|
+
* };
|
|
101
|
+
*
|
|
102
|
+
* isDateAfter({
|
|
103
|
+
* fullDate: exampleDate,
|
|
104
|
+
* relativeTo: {
|
|
105
|
+
* ...exampleDate,
|
|
106
|
+
* year: 1900,
|
|
107
|
+
* },
|
|
108
|
+
* }); // `true`
|
|
109
|
+
*
|
|
110
|
+
* isDateAfter({
|
|
111
|
+
* fullDate: exampleDate,
|
|
112
|
+
* relativeTo: {
|
|
113
|
+
* ...exampleDate,
|
|
114
|
+
* year: 3000,
|
|
115
|
+
* },
|
|
116
|
+
* }); // `false`
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
export function isDateAfter({ relativeTo, fullDate, }) {
|
|
120
|
+
return (diffDates({
|
|
121
|
+
start: relativeTo,
|
|
122
|
+
end: fullDate,
|
|
123
|
+
}, { milliseconds: true }).milliseconds >= 0);
|
|
124
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type PartialWithUndefined, type SetRequiredAndNotNull } from '@augment-vir/common';
|
|
2
|
+
import { type FullDate } from '../full-date/full-date-shape.js';
|
|
3
|
+
import type { Timezone } from '../timezone/timezones.js';
|
|
4
|
+
/**
|
|
5
|
+
* Checks that the input has all the requested {@link FullDate} keys.
|
|
6
|
+
*
|
|
7
|
+
* @category Util
|
|
8
|
+
* @example
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* import {hasFullDateKeys} from 'date-vir';
|
|
12
|
+
*
|
|
13
|
+
* hasFullDateKeys({year: 2024}, ['year']); // `true`
|
|
14
|
+
* hasFullDateKeys({year: 2024}, ['day']); // `false`
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function hasFullDateKeys<SpecificTimezone extends Timezone, PartialFullDate extends PartialWithUndefined<FullDate<SpecificTimezone>>,
|
|
18
|
+
/** A union of strings. */
|
|
19
|
+
RequiredKeys extends keyof FullDate<SpecificTimezone>>(partialFullDate: PartialWithUndefined<FullDate<SpecificTimezone>>, keys: ReadonlyArray<RequiredKeys>): partialFullDate is SetRequiredAndNotNull<PartialFullDate, RequiredKeys>;
|
|
20
|
+
/**
|
|
21
|
+
* Asserts that the input has all the requested {@link FullDate} keys.
|
|
22
|
+
*
|
|
23
|
+
* @category Util
|
|
24
|
+
* @example
|
|
25
|
+
*
|
|
26
|
+
* ```ts
|
|
27
|
+
* import {assertHasFullDateKeys} from 'date-vir';
|
|
28
|
+
*
|
|
29
|
+
* assertHasFullDateKeys({year: 2024}, ['year']); // passes
|
|
30
|
+
* assertHasFullDateKeys({year: 2024}, ['day']); // fails
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function assertHasFullDateKeys<SpecificTimezone extends Timezone, PartialFullDate extends PartialWithUndefined<FullDate<SpecificTimezone>>,
|
|
34
|
+
/** A union of strings. */
|
|
35
|
+
RequiredKeys extends keyof FullDate<SpecificTimezone>>(partialFullDate: PartialWithUndefined<FullDate<SpecificTimezone>>, keys: ReadonlyArray<RequiredKeys>): asserts partialFullDate is SetRequiredAndNotNull<PartialFullDate, RequiredKeys>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks that the input has all the requested {@link FullDate} keys.
|
|
3
|
+
*
|
|
4
|
+
* @category Util
|
|
5
|
+
* @example
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* import {hasFullDateKeys} from 'date-vir';
|
|
9
|
+
*
|
|
10
|
+
* hasFullDateKeys({year: 2024}, ['year']); // `true`
|
|
11
|
+
* hasFullDateKeys({year: 2024}, ['day']); // `false`
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export function hasFullDateKeys(partialFullDate, keys) {
|
|
15
|
+
try {
|
|
16
|
+
assertHasFullDateKeys(partialFullDate, keys);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Asserts that the input has all the requested {@link FullDate} keys.
|
|
25
|
+
*
|
|
26
|
+
* @category Util
|
|
27
|
+
* @example
|
|
28
|
+
*
|
|
29
|
+
* ```ts
|
|
30
|
+
* import {assertHasFullDateKeys} from 'date-vir';
|
|
31
|
+
*
|
|
32
|
+
* assertHasFullDateKeys({year: 2024}, ['year']); // passes
|
|
33
|
+
* assertHasFullDateKeys({year: 2024}, ['day']); // fails
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export function assertHasFullDateKeys(partialFullDate, keys) {
|
|
37
|
+
const missingKeys = [];
|
|
38
|
+
keys.forEach((key) => {
|
|
39
|
+
if (partialFullDate[key] == undefined) {
|
|
40
|
+
missingKeys.push(key);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
if (missingKeys.length) {
|
|
44
|
+
throw new Error(`Missing required FullDate key(s): ${missingKeys.join(', ')}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { FullDate } from '../full-date/full-date-shape.js';
|
|
2
|
+
/**
|
|
3
|
+
* Convert a {@link FullDate} from a built-in JS
|
|
4
|
+
* [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date).
|
|
5
|
+
*
|
|
6
|
+
* @category Conversion
|
|
7
|
+
* @example
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* import {toJsDate, type FullDate} from 'date-vir';
|
|
11
|
+
*
|
|
12
|
+
* const exampleDate: Readonly<FullDate> = {
|
|
13
|
+
* year: 2024,
|
|
14
|
+
* month: 1,
|
|
15
|
+
* day: 5,
|
|
16
|
+
* hour: 1,
|
|
17
|
+
* minute: 1,
|
|
18
|
+
* second: 1,
|
|
19
|
+
* millisecond: 1,
|
|
20
|
+
* timezone: 'UTC',
|
|
21
|
+
* };
|
|
22
|
+
*
|
|
23
|
+
* toJsDate(exampleDate);
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function toJsDate(fullDate: Readonly<FullDate>): Date;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { toTimestamp } from '../formatting/timestamp.js';
|
|
2
|
+
/**
|
|
3
|
+
* Convert a {@link FullDate} from a built-in JS
|
|
4
|
+
* [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date).
|
|
5
|
+
*
|
|
6
|
+
* @category Conversion
|
|
7
|
+
* @example
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* import {toJsDate, type FullDate} from 'date-vir';
|
|
11
|
+
*
|
|
12
|
+
* const exampleDate: Readonly<FullDate> = {
|
|
13
|
+
* year: 2024,
|
|
14
|
+
* month: 1,
|
|
15
|
+
* day: 5,
|
|
16
|
+
* hour: 1,
|
|
17
|
+
* minute: 1,
|
|
18
|
+
* second: 1,
|
|
19
|
+
* millisecond: 1,
|
|
20
|
+
* timezone: 'UTC',
|
|
21
|
+
* };
|
|
22
|
+
*
|
|
23
|
+
* toJsDate(exampleDate);
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function toJsDate(fullDate) {
|
|
27
|
+
return new Date(toTimestamp(fullDate));
|
|
28
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { UtcIsoString } from '../formatting/string-format-types.js';
|
|
2
|
+
import { FullDate } from '../full-date/full-date-shape.js';
|
|
3
|
+
import { Timezone, UtcTimezone } from '../timezone/timezones.js';
|
|
4
|
+
/**
|
|
5
|
+
* Get the time right now as a UTC ISO.
|
|
6
|
+
*
|
|
7
|
+
* @category Now
|
|
8
|
+
* @example
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* import {getNowInIsoString} from 'date-vir';
|
|
12
|
+
*
|
|
13
|
+
* getNowInIsoString();
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export declare function getNowInIsoString(): UtcIsoString;
|
|
17
|
+
/**
|
|
18
|
+
* Get the time right now as a {@link FullDate} represented in the current user's timezone.
|
|
19
|
+
*
|
|
20
|
+
* @category Now
|
|
21
|
+
* @example
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* import {getNowInUserTimezone} from 'date-vir';
|
|
25
|
+
*
|
|
26
|
+
* getNowInUserTimezone();
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function getNowInUserTimezone(): FullDate;
|
|
30
|
+
/**
|
|
31
|
+
* Get the time right now as a {@link FullDate} represented in the UTC timezone.
|
|
32
|
+
*
|
|
33
|
+
* @category Now
|
|
34
|
+
* @example
|
|
35
|
+
*
|
|
36
|
+
* ```ts
|
|
37
|
+
* import {getNowInUtcTimezone} from 'date-vir';
|
|
38
|
+
*
|
|
39
|
+
* getNowInUtcTimezone();
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare function getNowInUtcTimezone(): FullDate<UtcTimezone>;
|
|
43
|
+
/**
|
|
44
|
+
* Get the time right now as a {@link FullDate} represented in the given timezone.
|
|
45
|
+
*
|
|
46
|
+
* @category Now
|
|
47
|
+
* @example
|
|
48
|
+
*
|
|
49
|
+
* ```ts
|
|
50
|
+
* import {getNowFullDate, utcTimezone, timezones} from 'date-vir';
|
|
51
|
+
*
|
|
52
|
+
* getNowFullDate(utcTimezone);
|
|
53
|
+
* getNowFullDate(timezones['Australia/Brisbane']);
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare function getNowFullDate<const SpecificTimezone extends Timezone>(timezone: SpecificTimezone): FullDate<SpecificTimezone>;
|