date-vir 5.3.2 → 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.
Files changed (141) hide show
  1. package/LICENSE-MIT +1 -1
  2. package/README.md +28 -28
  3. package/dist/date-operations/calculate-relative-date.d.ts +17 -0
  4. package/dist/{esm/date-operations → date-operations}/calculate-relative-date.js +10 -1
  5. package/dist/date-operations/combine-dates.d.ts +43 -0
  6. package/dist/{esm/date-operations → date-operations}/combine-dates.js +6 -4
  7. package/dist/date-operations/diff-dates.d.ts +95 -0
  8. package/dist/date-operations/diff-dates.js +124 -0
  9. package/dist/extra-utils/has-date-props.d.ts +35 -0
  10. package/dist/extra-utils/has-date-props.js +46 -0
  11. package/dist/extra-utils/js-date-conversion.d.ts +26 -0
  12. package/dist/extra-utils/js-date-conversion.js +28 -0
  13. package/dist/extra-utils/now.d.ts +56 -0
  14. package/dist/extra-utils/now.js +68 -0
  15. package/dist/extra-utils/override-date.d.ts +27 -0
  16. package/dist/extra-utils/override-date.js +27 -0
  17. package/dist/extra-utils/zero.d.ts +99 -0
  18. package/dist/extra-utils/zero.js +94 -0
  19. package/dist/formatting/formatted-string.d.ts +58 -0
  20. package/dist/formatting/formatted-string.js +73 -0
  21. package/dist/formatting/html-input.d.ts +30 -0
  22. package/dist/formatting/html-input.js +47 -0
  23. package/dist/formatting/relative-string.d.ts +53 -0
  24. package/dist/formatting/relative-string.js +93 -0
  25. package/dist/formatting/simple-strings.d.ts +187 -0
  26. package/dist/formatting/simple-strings.js +120 -0
  27. package/dist/formatting/string-format-types.d.ts +59 -0
  28. package/dist/formatting/string-format-types.js +19 -0
  29. package/dist/formatting/timestamp.d.ts +51 -0
  30. package/dist/formatting/timestamp.js +61 -0
  31. package/dist/full-date/create-full-date.d.ts +91 -0
  32. package/dist/full-date/create-full-date.js +142 -0
  33. package/dist/full-date/date-like.d.ts +9 -0
  34. package/dist/{esm/full-date → full-date}/format-presets.d.ts +4 -2
  35. package/dist/{esm/full-date → full-date}/format-presets.js +4 -2
  36. package/dist/full-date/full-date-parts.d.ts +48 -0
  37. package/dist/full-date/full-date-parts.js +45 -0
  38. package/dist/full-date/full-date-shape.d.ts +106 -0
  39. package/dist/{esm/full-date → full-date}/full-date-shape.js +15 -22
  40. package/dist/full-date/is-valid-full-date.d.ts +21 -0
  41. package/dist/full-date/is-valid-full-date.js +38 -0
  42. package/dist/full-date/luxon-date-time-conversion.d.ts +19 -0
  43. package/dist/{esm/full-date → full-date}/luxon-date-time-conversion.js +10 -6
  44. package/dist/full-date/parsing.d.ts +33 -0
  45. package/dist/full-date/parsing.js +47 -0
  46. package/dist/full-date/string-parsing.d.ts +9 -0
  47. package/dist/{esm/full-date → full-date}/string-parsing.js +6 -0
  48. package/dist/index.d.ts +27 -0
  49. package/dist/index.js +27 -0
  50. package/dist/locales.d.ts +6 -0
  51. package/dist/locales.js +7 -0
  52. package/dist/timezone/timezone-checks.d.ts +21 -0
  53. package/dist/timezone/timezone-checks.js +34 -0
  54. package/dist/{esm/timezone → timezone}/timezone-names.d.ts +11 -5
  55. package/dist/{esm/timezone → timezone}/timezone-names.js +11 -3
  56. package/dist/timezone/timezones.d.ts +42 -0
  57. package/dist/timezone/timezones.js +31 -0
  58. package/package.json +30 -48
  59. package/cspell.config.cjs +0 -13
  60. package/dist/cjs/date-operations/calculate-relative-date.js +0 -12
  61. package/dist/cjs/date-operations/combine-dates.js +0 -50
  62. package/dist/cjs/date-operations/diff-dates.js +0 -105
  63. package/dist/cjs/duration/duration-unit.js +0 -41
  64. package/dist/cjs/duration/duration-utils.js +0 -42
  65. package/dist/cjs/duration/duration.js +0 -2
  66. package/dist/cjs/extra-utils/date-transforms.js +0 -8
  67. package/dist/cjs/extra-utils/has-date-props.js +0 -25
  68. package/dist/cjs/extra-utils/js-date-conversion.js +0 -8
  69. package/dist/cjs/extra-utils/now.js +0 -22
  70. package/dist/cjs/extra-utils/zero.js +0 -31
  71. package/dist/cjs/formatting/formatted-string.js +0 -34
  72. package/dist/cjs/formatting/html-input.js +0 -37
  73. package/dist/cjs/formatting/relative-string.js +0 -77
  74. package/dist/cjs/formatting/simple-strings.js +0 -58
  75. package/dist/cjs/formatting/string-format-types.js +0 -9
  76. package/dist/cjs/formatting/timestamp.js +0 -21
  77. package/dist/cjs/full-date/create-full-date.js +0 -81
  78. package/dist/cjs/full-date/date-like.js +0 -2
  79. package/dist/cjs/full-date/format-presets.js +0 -32
  80. package/dist/cjs/full-date/full-date-shape.js +0 -54
  81. package/dist/cjs/full-date/is-valid-full-date.js +0 -28
  82. package/dist/cjs/full-date/luxon-date-time-conversion.js +0 -43
  83. package/dist/cjs/full-date/parsing.js +0 -48
  84. package/dist/cjs/full-date/string-parsing.js +0 -33
  85. package/dist/cjs/index.js +0 -44
  86. package/dist/cjs/locales.js +0 -5
  87. package/dist/cjs/timezone/timezone-checks.js +0 -34
  88. package/dist/cjs/timezone/timezone-names.js +0 -479
  89. package/dist/cjs/timezone/timezones.js +0 -14
  90. package/dist/esm/date-operations/calculate-relative-date.d.ts +0 -8
  91. package/dist/esm/date-operations/combine-dates.d.ts +0 -35
  92. package/dist/esm/date-operations/diff-dates.d.ts +0 -66
  93. package/dist/esm/date-operations/diff-dates.js +0 -100
  94. package/dist/esm/duration/duration-unit.d.ts +0 -27
  95. package/dist/esm/duration/duration-unit.js +0 -38
  96. package/dist/esm/duration/duration-utils.d.ts +0 -11
  97. package/dist/esm/duration/duration-utils.js +0 -37
  98. package/dist/esm/duration/duration.d.ts +0 -32
  99. package/dist/esm/duration/duration.js +0 -1
  100. package/dist/esm/extra-utils/date-transforms.d.ts +0 -4
  101. package/dist/esm/extra-utils/date-transforms.js +0 -4
  102. package/dist/esm/extra-utils/has-date-props.d.ts +0 -9
  103. package/dist/esm/extra-utils/has-date-props.js +0 -20
  104. package/dist/esm/extra-utils/js-date-conversion.d.ts +0 -2
  105. package/dist/esm/extra-utils/js-date-conversion.js +0 -4
  106. package/dist/esm/extra-utils/now.d.ts +0 -6
  107. package/dist/esm/extra-utils/now.js +0 -16
  108. package/dist/esm/extra-utils/zero.d.ts +0 -31
  109. package/dist/esm/extra-utils/zero.js +0 -26
  110. package/dist/esm/formatting/formatted-string.d.ts +0 -14
  111. package/dist/esm/formatting/formatted-string.js +0 -29
  112. package/dist/esm/formatting/html-input.d.ts +0 -19
  113. package/dist/esm/formatting/html-input.js +0 -33
  114. package/dist/esm/formatting/relative-string.d.ts +0 -31
  115. package/dist/esm/formatting/relative-string.js +0 -73
  116. package/dist/esm/formatting/simple-strings.d.ts +0 -71
  117. package/dist/esm/formatting/simple-strings.js +0 -51
  118. package/dist/esm/formatting/string-format-types.d.ts +0 -7
  119. package/dist/esm/formatting/string-format-types.js +0 -5
  120. package/dist/esm/formatting/timestamp.d.ts +0 -6
  121. package/dist/esm/formatting/timestamp.js +0 -16
  122. package/dist/esm/full-date/create-full-date.d.ts +0 -21
  123. package/dist/esm/full-date/create-full-date.js +0 -73
  124. package/dist/esm/full-date/date-like.d.ts +0 -5
  125. package/dist/esm/full-date/full-date-shape.d.ts +0 -80
  126. package/dist/esm/full-date/is-valid-full-date.d.ts +0 -5
  127. package/dist/esm/full-date/is-valid-full-date.js +0 -22
  128. package/dist/esm/full-date/luxon-date-time-conversion.d.ts +0 -15
  129. package/dist/esm/full-date/parsing.d.ts +0 -27
  130. package/dist/esm/full-date/parsing.js +0 -43
  131. package/dist/esm/full-date/string-parsing.d.ts +0 -3
  132. package/dist/esm/index.d.ts +0 -28
  133. package/dist/esm/index.js +0 -28
  134. package/dist/esm/locales.d.ts +0 -1
  135. package/dist/esm/locales.js +0 -2
  136. package/dist/esm/timezone/timezone-checks.d.ts +0 -17
  137. package/dist/esm/timezone/timezone-checks.js +0 -29
  138. package/dist/esm/timezone/timezones.d.ts +0 -480
  139. package/dist/esm/timezone/timezones.js +0 -11
  140. package/public/index.css +0 -7
  141. /package/dist/{esm/full-date → full-date}/date-like.js +0 -0
package/LICENSE-MIT CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023 electrovir
3
+ Copyright (c) 2024 electrovir
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
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, timezones} from 'date-vir';
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: timezones.UTC,
24
+ timezone: utcTimezone,
25
25
  };
26
26
  ```
27
27
 
28
- # Creating a FullDate
28
+ ## Creating a FullDate
29
29
 
30
- Several functions are available for creating `FullDate` objects, with `createFullDate` being the most commonly used:
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
- parseStrangeString,
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', timezones['Europe/Rome']);
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(timezones['America/Argentina/Buenos_Aires']);
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'), timezones['Asia/Tokyo']);
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
- parseStrangeString({
65
+ parseDateStringWithPattern({
66
66
  dateString: '870-0-14-19 5 2023 6',
67
67
  formatString: 'S-s-h-m d yyyy M',
68
- timezone: timezones['America/Cancun'],
68
+ timezone: Timezone['America/Cancun'],
69
69
  });
70
70
  ```
71
71
 
72
- # Outputs
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
- timezones,
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', timezones['America/Chicago']);
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
- toIsoString(myFullDate); // returns '2023-06-05T14:19:00.870Z'
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, FullDatePartEnum.Date); // returns '2023-06-05'
116
+ toHtmlInputString(myFullDate, FullDatePart.Date); // returns '2023-06-05'
117
117
  ```
118
118
 
119
- # Timezone
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 {timezones, userTimezone, utcTimezone} from 'date-vir';
126
+ import {Timezone, userTimezone, utcTimezone} from 'date-vir';
127
127
 
128
- timezones['Africa/Abidjan'];
129
- timezones['America/Los_Angeles'];
130
- timezones['Etc/GMT+1'];
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
- # Luxon
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, timezones, toLuxonDateTime} from 'date-vir';
145
+ import {createFullDate, Timezone, toLuxonDateTime} from 'date-vir';
146
146
 
147
- const myFullDate = createFullDate('2023-06-05T14:19:00.870Z', timezones['America/Chicago']);
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 { FullDatePartEnum, datePartShape, timePartShape, } from '../full-date/full-date-shape';
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 timezones must
5
- * match for both inputs. If two complete FullDate objects are passed in, only the respective parts
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>;