date-vir 5.3.2 → 7.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.
Files changed (147) 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/date-position.d.ts +149 -0
  8. package/dist/date-operations/date-position.js +175 -0
  9. package/dist/date-operations/diff-dates.d.ts +95 -0
  10. package/dist/date-operations/diff-dates.js +124 -0
  11. package/dist/extra-utils/end.d.ts +11 -0
  12. package/dist/extra-utils/end.js +11 -0
  13. package/dist/extra-utils/has-date-props.d.ts +35 -0
  14. package/dist/extra-utils/has-date-props.js +46 -0
  15. package/dist/extra-utils/js-date-conversion.d.ts +26 -0
  16. package/dist/extra-utils/js-date-conversion.js +28 -0
  17. package/dist/extra-utils/now.d.ts +56 -0
  18. package/dist/extra-utils/now.js +68 -0
  19. package/dist/extra-utils/override-date.d.ts +27 -0
  20. package/dist/extra-utils/override-date.js +27 -0
  21. package/dist/extra-utils/zero.d.ts +109 -0
  22. package/dist/extra-utils/zero.js +94 -0
  23. package/dist/formatting/formatted-string.d.ts +58 -0
  24. package/dist/formatting/formatted-string.js +73 -0
  25. package/dist/formatting/html-input.d.ts +30 -0
  26. package/dist/formatting/html-input.js +47 -0
  27. package/dist/formatting/relative-string.d.ts +53 -0
  28. package/dist/formatting/relative-string.js +93 -0
  29. package/dist/formatting/simple-strings.d.ts +187 -0
  30. package/dist/formatting/simple-strings.js +120 -0
  31. package/dist/formatting/string-format-types.d.ts +59 -0
  32. package/dist/formatting/string-format-types.js +19 -0
  33. package/dist/formatting/timestamp.d.ts +51 -0
  34. package/dist/formatting/timestamp.js +61 -0
  35. package/dist/full-date/create-full-date.d.ts +91 -0
  36. package/dist/full-date/create-full-date.js +142 -0
  37. package/dist/full-date/date-like.d.ts +9 -0
  38. package/dist/{esm/full-date → full-date}/format-presets.d.ts +4 -2
  39. package/dist/{esm/full-date → full-date}/format-presets.js +4 -2
  40. package/dist/full-date/full-date-parts.d.ts +44 -0
  41. package/dist/full-date/full-date-parts.js +47 -0
  42. package/dist/full-date/full-date-shape.d.ts +108 -0
  43. package/dist/full-date/full-date-shape.js +45 -0
  44. package/dist/full-date/is-valid-full-date.d.ts +21 -0
  45. package/dist/full-date/is-valid-full-date.js +38 -0
  46. package/dist/full-date/luxon-date-time-conversion.d.ts +19 -0
  47. package/dist/full-date/luxon-date-time-conversion.js +43 -0
  48. package/dist/full-date/parsing.d.ts +33 -0
  49. package/dist/full-date/parsing.js +47 -0
  50. package/dist/full-date/string-parsing.d.ts +9 -0
  51. package/dist/{esm/full-date → full-date}/string-parsing.js +6 -0
  52. package/dist/index.d.ts +29 -0
  53. package/dist/index.js +29 -0
  54. package/dist/locales.d.ts +6 -0
  55. package/dist/locales.js +7 -0
  56. package/dist/timezone/timezone-checks.d.ts +21 -0
  57. package/dist/timezone/timezone-checks.js +34 -0
  58. package/dist/{esm/timezone → timezone}/timezone-names.d.ts +11 -5
  59. package/dist/{esm/timezone → timezone}/timezone-names.js +11 -3
  60. package/dist/timezone/timezones.d.ts +42 -0
  61. package/dist/timezone/timezones.js +31 -0
  62. package/package.json +33 -51
  63. package/cspell.config.cjs +0 -13
  64. package/dist/cjs/date-operations/calculate-relative-date.js +0 -12
  65. package/dist/cjs/date-operations/combine-dates.js +0 -50
  66. package/dist/cjs/date-operations/diff-dates.js +0 -105
  67. package/dist/cjs/duration/duration-unit.js +0 -41
  68. package/dist/cjs/duration/duration-utils.js +0 -42
  69. package/dist/cjs/duration/duration.js +0 -2
  70. package/dist/cjs/extra-utils/date-transforms.js +0 -8
  71. package/dist/cjs/extra-utils/has-date-props.js +0 -25
  72. package/dist/cjs/extra-utils/js-date-conversion.js +0 -8
  73. package/dist/cjs/extra-utils/now.js +0 -22
  74. package/dist/cjs/extra-utils/zero.js +0 -31
  75. package/dist/cjs/formatting/formatted-string.js +0 -34
  76. package/dist/cjs/formatting/html-input.js +0 -37
  77. package/dist/cjs/formatting/relative-string.js +0 -77
  78. package/dist/cjs/formatting/simple-strings.js +0 -58
  79. package/dist/cjs/formatting/string-format-types.js +0 -9
  80. package/dist/cjs/formatting/timestamp.js +0 -21
  81. package/dist/cjs/full-date/create-full-date.js +0 -81
  82. package/dist/cjs/full-date/date-like.js +0 -2
  83. package/dist/cjs/full-date/format-presets.js +0 -32
  84. package/dist/cjs/full-date/full-date-shape.js +0 -54
  85. package/dist/cjs/full-date/is-valid-full-date.js +0 -28
  86. package/dist/cjs/full-date/luxon-date-time-conversion.js +0 -43
  87. package/dist/cjs/full-date/parsing.js +0 -48
  88. package/dist/cjs/full-date/string-parsing.js +0 -33
  89. package/dist/cjs/index.js +0 -44
  90. package/dist/cjs/locales.js +0 -5
  91. package/dist/cjs/timezone/timezone-checks.js +0 -34
  92. package/dist/cjs/timezone/timezone-names.js +0 -479
  93. package/dist/cjs/timezone/timezones.js +0 -14
  94. package/dist/esm/date-operations/calculate-relative-date.d.ts +0 -8
  95. package/dist/esm/date-operations/combine-dates.d.ts +0 -35
  96. package/dist/esm/date-operations/diff-dates.d.ts +0 -66
  97. package/dist/esm/date-operations/diff-dates.js +0 -100
  98. package/dist/esm/duration/duration-unit.d.ts +0 -27
  99. package/dist/esm/duration/duration-unit.js +0 -38
  100. package/dist/esm/duration/duration-utils.d.ts +0 -11
  101. package/dist/esm/duration/duration-utils.js +0 -37
  102. package/dist/esm/duration/duration.d.ts +0 -32
  103. package/dist/esm/duration/duration.js +0 -1
  104. package/dist/esm/extra-utils/date-transforms.d.ts +0 -4
  105. package/dist/esm/extra-utils/date-transforms.js +0 -4
  106. package/dist/esm/extra-utils/has-date-props.d.ts +0 -9
  107. package/dist/esm/extra-utils/has-date-props.js +0 -20
  108. package/dist/esm/extra-utils/js-date-conversion.d.ts +0 -2
  109. package/dist/esm/extra-utils/js-date-conversion.js +0 -4
  110. package/dist/esm/extra-utils/now.d.ts +0 -6
  111. package/dist/esm/extra-utils/now.js +0 -16
  112. package/dist/esm/extra-utils/zero.d.ts +0 -31
  113. package/dist/esm/extra-utils/zero.js +0 -26
  114. package/dist/esm/formatting/formatted-string.d.ts +0 -14
  115. package/dist/esm/formatting/formatted-string.js +0 -29
  116. package/dist/esm/formatting/html-input.d.ts +0 -19
  117. package/dist/esm/formatting/html-input.js +0 -33
  118. package/dist/esm/formatting/relative-string.d.ts +0 -31
  119. package/dist/esm/formatting/relative-string.js +0 -73
  120. package/dist/esm/formatting/simple-strings.d.ts +0 -71
  121. package/dist/esm/formatting/simple-strings.js +0 -51
  122. package/dist/esm/formatting/string-format-types.d.ts +0 -7
  123. package/dist/esm/formatting/string-format-types.js +0 -5
  124. package/dist/esm/formatting/timestamp.d.ts +0 -6
  125. package/dist/esm/formatting/timestamp.js +0 -16
  126. package/dist/esm/full-date/create-full-date.d.ts +0 -21
  127. package/dist/esm/full-date/create-full-date.js +0 -73
  128. package/dist/esm/full-date/date-like.d.ts +0 -5
  129. package/dist/esm/full-date/full-date-shape.d.ts +0 -80
  130. package/dist/esm/full-date/full-date-shape.js +0 -51
  131. package/dist/esm/full-date/is-valid-full-date.d.ts +0 -5
  132. package/dist/esm/full-date/is-valid-full-date.js +0 -22
  133. package/dist/esm/full-date/luxon-date-time-conversion.d.ts +0 -15
  134. package/dist/esm/full-date/luxon-date-time-conversion.js +0 -38
  135. package/dist/esm/full-date/parsing.d.ts +0 -27
  136. package/dist/esm/full-date/parsing.js +0 -43
  137. package/dist/esm/full-date/string-parsing.d.ts +0 -3
  138. package/dist/esm/index.d.ts +0 -28
  139. package/dist/esm/index.js +0 -28
  140. package/dist/esm/locales.d.ts +0 -1
  141. package/dist/esm/locales.js +0 -2
  142. package/dist/esm/timezone/timezone-checks.d.ts +0 -17
  143. package/dist/esm/timezone/timezone-checks.js +0 -29
  144. package/dist/esm/timezone/timezones.d.ts +0 -480
  145. package/dist/esm/timezone/timezones.js +0 -11
  146. package/public/index.css +0 -7
  147. /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,149 @@
1
+ import { DateUnit } from '@date-vir/duration';
2
+ import { type FullDate } from '../full-date/full-date-shape.js';
3
+ import { Timezone } from '../timezone/timezones.js';
4
+ /**
5
+ * Get the {@link DateUnit} value of a {@link FullDate}.
6
+ *
7
+ * @category Calculation
8
+ * @example
9
+ *
10
+ * ```ts
11
+ * import {getDateUnit, DateUnit, utcTimezone} from 'date-vir';
12
+ *
13
+ * getDateUnit(
14
+ * {
15
+ * year: 2024,
16
+ * month: 11,
17
+ * day: 7,
18
+ *
19
+ * hour: 12,
20
+ * minute: 12,
21
+ * second: 12,
22
+ * millisecond: 12,
23
+ *
24
+ * timezone: utcTimezone,
25
+ * },
26
+ * DateUnit.Week,
27
+ * ); // outputs `45`
28
+ * ```
29
+ */
30
+ export declare function getDateUnit(date: Readonly<FullDate>, unit: DateUnit): number;
31
+ /**
32
+ * Get the start date of a specific {@link DateUnit} based on a given {@link FullDate}.
33
+ *
34
+ * @category Calculation
35
+ * @example
36
+ *
37
+ * ```ts
38
+ * import {getStartDate, DateUnit, utcTimezone} from 'date-vir';
39
+ *
40
+ * getStartDate(
41
+ * {
42
+ * year: 2024,
43
+ * month: 11,
44
+ * day: 7,
45
+ *
46
+ * hour: 12,
47
+ * minute: 12,
48
+ * second: 12,
49
+ * millisecond: 12,
50
+ *
51
+ * timezone: utcTimezone,
52
+ * },
53
+ * DateUnit.Month,
54
+ * ); // outputs {year: 2024, month: 11, day: 1, hour: 0, minute: 0, second: 0, millisecond: 0, timezone: utcTimezone}
55
+ * ```
56
+ */
57
+ export declare function getStartDate<const SpecificTimezone extends Timezone>(date: Readonly<FullDate<SpecificTimezone>>, unit: DateUnit): FullDate<SpecificTimezone>;
58
+ /**
59
+ * Get the end date of a specific {@link DateUnit} based on a given {@link FullDate}.
60
+ *
61
+ * @category Calculation
62
+ * @example
63
+ *
64
+ * ```ts
65
+ * import {getEndDate, DateUnit, utcTimezone} from 'date-vir';
66
+ *
67
+ * getEndDate(
68
+ * {
69
+ * year: 2024,
70
+ * month: 11,
71
+ * day: 7,
72
+ *
73
+ * hour: 12,
74
+ * minute: 12,
75
+ * second: 12,
76
+ * millisecond: 12,
77
+ *
78
+ * timezone: utcTimezone,
79
+ * },
80
+ * DateUnit.Month,
81
+ * ); // outputs {year: 2024, month: 11, day: 30, hour: 23, minute: 59, second: 59, millisecond: 999, timezone: utcTimezone}
82
+ * ```
83
+ */
84
+ export declare function getEndDate<const SpecificTimezone extends Timezone>(date: Readonly<FullDate<SpecificTimezone>>, unit: DateUnit): FullDate<SpecificTimezone>;
85
+ /**
86
+ * Shape definition for all valid date position calculations. Used for {@link calculateDatePosition}.
87
+ *
88
+ * @category Internal
89
+ */
90
+ export declare const datePositionCalculationShape: import("object-shape-tester").ShapeDefinition<import("object-shape-tester").ShapeOr<[{
91
+ get: import("object-shape-tester").ShapeExact<readonly [DateUnit.Month]>;
92
+ in: import("object-shape-tester").ShapeOr<[import("object-shape-tester").ShapeExact<readonly [DateUnit.Year]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Quarter]>]>;
93
+ }, {
94
+ get: import("object-shape-tester").ShapeExact<readonly [DateUnit.Week]>;
95
+ in: import("object-shape-tester").ShapeOr<[import("object-shape-tester").ShapeExact<readonly [DateUnit.Year]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Quarter]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Month]>]>;
96
+ }, {
97
+ get: import("object-shape-tester").ShapeExact<readonly [DateUnit.Day]>;
98
+ in: import("object-shape-tester").ShapeOr<[import("object-shape-tester").ShapeExact<readonly [DateUnit.Year]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Quarter]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Month]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Week]>]>;
99
+ }, {
100
+ get: import("object-shape-tester").ShapeExact<readonly [DateUnit.Hour]>;
101
+ in: import("object-shape-tester").ShapeOr<[import("object-shape-tester").ShapeExact<readonly [DateUnit.Year]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Quarter]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Month]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Week]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Day]>]>;
102
+ }, {
103
+ get: import("object-shape-tester").ShapeExact<readonly [DateUnit.Minute]>;
104
+ in: import("object-shape-tester").ShapeOr<[import("object-shape-tester").ShapeExact<readonly [DateUnit.Year]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Quarter]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Month]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Week]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Day]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Hour]>]>;
105
+ }, {
106
+ get: import("object-shape-tester").ShapeExact<readonly [DateUnit.Second]>;
107
+ in: import("object-shape-tester").ShapeOr<[import("object-shape-tester").ShapeExact<readonly [DateUnit.Year]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Quarter]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Month]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Week]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Day]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Hour]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Minute]>]>;
108
+ }, {
109
+ get: import("object-shape-tester").ShapeExact<readonly [DateUnit.Millisecond]>;
110
+ in: import("object-shape-tester").ShapeOr<[import("object-shape-tester").ShapeExact<readonly [DateUnit.Year]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Quarter]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Month]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Week]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Day]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Hour]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Minute]>, import("object-shape-tester").ShapeExact<readonly [DateUnit.Second]>]>;
111
+ }]>, false>;
112
+ /**
113
+ * All valid date position calculations. Used for {@link calculateDatePosition}.
114
+ *
115
+ * @category Internal
116
+ */
117
+ export type DatePositionCalculation = typeof datePositionCalculationShape.runtimeType;
118
+ /**
119
+ * Calculate the position of the given date's day within the given date unit. Only date units larger
120
+ * than a day are allowed.
121
+ *
122
+ * @category Calculation
123
+ * @example
124
+ *
125
+ * ```ts
126
+ * import {calculateDatePosition, DateUnit} from 'date-vir';
127
+ *
128
+ * calculateDatePosition(
129
+ * {
130
+ * day: 5,
131
+ * month: 4,
132
+ * year: 2020,
133
+ * },
134
+ * DateUnit.Month,
135
+ * );
136
+ * // result is 5
137
+ *
138
+ * calculateDatePosition(
139
+ * {
140
+ * day: 5,
141
+ * month: 4,
142
+ * year: 2020,
143
+ * },
144
+ * DateUnit.Week,
145
+ * );
146
+ * // result is
147
+ * ```
148
+ */
149
+ export declare function calculateDatePosition(date: Readonly<FullDate>, calculation: Readonly<DatePositionCalculation>): number;
@@ -0,0 +1,175 @@
1
+ import { check } from '@augment-vir/assert';
2
+ import { stringify } from '@augment-vir/common';
3
+ import { DateUnit, oneIndexedDateUnits } from '@date-vir/duration';
4
+ import { defineShape, exact, isValidShape, or } from 'object-shape-tester';
5
+ import { createFullDate } from '../full-date/create-full-date.js';
6
+ import { toLuxonDateTime } from '../full-date/luxon-date-time-conversion.js';
7
+ import { diffDates } from './diff-dates.js';
8
+ /**
9
+ * Get the {@link DateUnit} value of a {@link FullDate}.
10
+ *
11
+ * @category Calculation
12
+ * @example
13
+ *
14
+ * ```ts
15
+ * import {getDateUnit, DateUnit, utcTimezone} from 'date-vir';
16
+ *
17
+ * getDateUnit(
18
+ * {
19
+ * year: 2024,
20
+ * month: 11,
21
+ * day: 7,
22
+ *
23
+ * hour: 12,
24
+ * minute: 12,
25
+ * second: 12,
26
+ * millisecond: 12,
27
+ *
28
+ * timezone: utcTimezone,
29
+ * },
30
+ * DateUnit.Week,
31
+ * ); // outputs `45`
32
+ * ```
33
+ */
34
+ export function getDateUnit(date, unit) {
35
+ const luxonInstance = toLuxonDateTime(date);
36
+ if (unit === DateUnit.Week) {
37
+ return luxonInstance.weekNumber;
38
+ }
39
+ else {
40
+ return luxonInstance[unit];
41
+ }
42
+ }
43
+ /**
44
+ * Get the start date of a specific {@link DateUnit} based on a given {@link FullDate}.
45
+ *
46
+ * @category Calculation
47
+ * @example
48
+ *
49
+ * ```ts
50
+ * import {getStartDate, DateUnit, utcTimezone} from 'date-vir';
51
+ *
52
+ * getStartDate(
53
+ * {
54
+ * year: 2024,
55
+ * month: 11,
56
+ * day: 7,
57
+ *
58
+ * hour: 12,
59
+ * minute: 12,
60
+ * second: 12,
61
+ * millisecond: 12,
62
+ *
63
+ * timezone: utcTimezone,
64
+ * },
65
+ * DateUnit.Month,
66
+ * ); // outputs {year: 2024, month: 11, day: 1, hour: 0, minute: 0, second: 0, millisecond: 0, timezone: utcTimezone}
67
+ * ```
68
+ */
69
+ export function getStartDate(date, unit) {
70
+ const luxonInstance = toLuxonDateTime(date);
71
+ return createFullDate(luxonInstance.startOf(unit), date.timezone);
72
+ }
73
+ /**
74
+ * Get the end date of a specific {@link DateUnit} based on a given {@link FullDate}.
75
+ *
76
+ * @category Calculation
77
+ * @example
78
+ *
79
+ * ```ts
80
+ * import {getEndDate, DateUnit, utcTimezone} from 'date-vir';
81
+ *
82
+ * getEndDate(
83
+ * {
84
+ * year: 2024,
85
+ * month: 11,
86
+ * day: 7,
87
+ *
88
+ * hour: 12,
89
+ * minute: 12,
90
+ * second: 12,
91
+ * millisecond: 12,
92
+ *
93
+ * timezone: utcTimezone,
94
+ * },
95
+ * DateUnit.Month,
96
+ * ); // outputs {year: 2024, month: 11, day: 30, hour: 23, minute: 59, second: 59, millisecond: 999, timezone: utcTimezone}
97
+ * ```
98
+ */
99
+ export function getEndDate(date, unit) {
100
+ const luxonInstance = toLuxonDateTime(date);
101
+ return createFullDate(luxonInstance.endOf(unit), date.timezone);
102
+ }
103
+ /**
104
+ * Shape definition for all valid date position calculations. Used for {@link calculateDatePosition}.
105
+ *
106
+ * @category Internal
107
+ */
108
+ export const datePositionCalculationShape = defineShape(or({
109
+ get: exact(DateUnit.Month),
110
+ in: or(exact(DateUnit.Year), exact(DateUnit.Quarter)),
111
+ }, {
112
+ get: exact(DateUnit.Week),
113
+ in: or(exact(DateUnit.Year), exact(DateUnit.Quarter), exact(DateUnit.Month)),
114
+ }, {
115
+ get: exact(DateUnit.Day),
116
+ in: or(exact(DateUnit.Year), exact(DateUnit.Quarter), exact(DateUnit.Month), exact(DateUnit.Week)),
117
+ }, {
118
+ get: exact(DateUnit.Hour),
119
+ in: or(exact(DateUnit.Year), exact(DateUnit.Quarter), exact(DateUnit.Month), exact(DateUnit.Week), exact(DateUnit.Day)),
120
+ }, {
121
+ get: exact(DateUnit.Minute),
122
+ in: or(exact(DateUnit.Year), exact(DateUnit.Quarter), exact(DateUnit.Month), exact(DateUnit.Week), exact(DateUnit.Day), exact(DateUnit.Hour)),
123
+ }, {
124
+ get: exact(DateUnit.Second),
125
+ in: or(exact(DateUnit.Year), exact(DateUnit.Quarter), exact(DateUnit.Month), exact(DateUnit.Week), exact(DateUnit.Day), exact(DateUnit.Hour), exact(DateUnit.Minute)),
126
+ }, {
127
+ get: exact(DateUnit.Millisecond),
128
+ in: or(exact(DateUnit.Year), exact(DateUnit.Quarter), exact(DateUnit.Month), exact(DateUnit.Week), exact(DateUnit.Day), exact(DateUnit.Hour), exact(DateUnit.Minute), exact(DateUnit.Second)),
129
+ }));
130
+ /**
131
+ * Calculate the position of the given date's day within the given date unit. Only date units larger
132
+ * than a day are allowed.
133
+ *
134
+ * @category Calculation
135
+ * @example
136
+ *
137
+ * ```ts
138
+ * import {calculateDatePosition, DateUnit} from 'date-vir';
139
+ *
140
+ * calculateDatePosition(
141
+ * {
142
+ * day: 5,
143
+ * month: 4,
144
+ * year: 2020,
145
+ * },
146
+ * DateUnit.Month,
147
+ * );
148
+ * // result is 5
149
+ *
150
+ * calculateDatePosition(
151
+ * {
152
+ * day: 5,
153
+ * month: 4,
154
+ * year: 2020,
155
+ * },
156
+ * DateUnit.Week,
157
+ * );
158
+ * // result is
159
+ * ```
160
+ */
161
+ export function calculateDatePosition(date, calculation) {
162
+ if (!isValidShape(calculation, datePositionCalculationShape)) {
163
+ throw new Error(`Invalid date position calculation for '${stringify(date)}': cannot get ${calculation.get} in ${calculation.in}.`);
164
+ }
165
+ const start = getStartDate(date, calculation.in);
166
+ const diffUnit = `${calculation.get}s`;
167
+ const diff = diffDates({ start, end: date }, { [diffUnit]: true });
168
+ const value = diff[diffUnit];
169
+ if (check.isIn(calculation.get, oneIndexedDateUnits)) {
170
+ return value + 1;
171
+ }
172
+ else {
173
+ return value;
174
+ }
175
+ }