date-vir 8.6.2 → 8.6.3

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 (39) hide show
  1. package/README.md +13 -13
  2. package/dist/date-operations/calculate-relative-date.d.ts +2 -1
  3. package/dist/date-operations/combine-dates.d.ts +9 -8
  4. package/dist/date-operations/combine-dates.js +3 -1
  5. package/dist/date-operations/date-position.d.ts +3 -2
  6. package/dist/date-operations/diff-dates.d.ts +4 -4
  7. package/dist/date-operations/diff-dates.js +4 -4
  8. package/dist/extra-utils/has-date-props.d.ts +3 -2
  9. package/dist/extra-utils/js-date-conversion.d.ts +2 -2
  10. package/dist/extra-utils/js-date-conversion.js +2 -2
  11. package/dist/extra-utils/now.d.ts +4 -4
  12. package/dist/extra-utils/now.js +2 -2
  13. package/dist/extra-utils/override-date.d.ts +5 -4
  14. package/dist/extra-utils/override-date.js +3 -3
  15. package/dist/extra-utils/zero.d.ts +9 -8
  16. package/dist/extra-utils/zero.js +6 -6
  17. package/dist/formatting/relative-string.js +3 -1
  18. package/dist/formatting/simple-strings.d.ts +7 -6
  19. package/dist/formatting/simple-strings.js +1 -1
  20. package/dist/formatting/timestamp.d.ts +6 -6
  21. package/dist/formatting/timestamp.js +6 -6
  22. package/dist/full-date/create-full-date.d.ts +10 -10
  23. package/dist/full-date/create-full-date.js +7 -7
  24. package/dist/full-date/date-like.d.ts +2 -1
  25. package/dist/full-date/full-date-shape.d.ts +10 -9
  26. package/dist/full-date/is-valid-full-date.d.ts +2 -1
  27. package/dist/full-date/luxon-date-time-conversion.d.ts +2 -1
  28. package/dist/full-date/luxon-date-time-conversion.js +7 -2
  29. package/dist/full-date/maybe-create-date.d.ts +2 -1
  30. package/dist/full-date/parsing.d.ts +3 -2
  31. package/dist/full-date/string-parsing.d.ts +2 -1
  32. package/dist/full-date/string-parsing.js +0 -1
  33. package/dist/timezone/timezone-checks.d.ts +15 -2
  34. package/dist/timezone/timezone-checks.js +25 -8
  35. package/dist/timezone/timezone-shape.d.ts +4 -3
  36. package/dist/timezone/timezone-shape.js +2 -2
  37. package/dist/timezone/timezones.d.ts +21 -8
  38. package/dist/timezone/timezones.js +6 -5
  39. package/package.json +16 -15
@@ -8,7 +8,7 @@ import { utcTimezone } from '../timezone/timezones.js';
8
8
  * @example
9
9
  *
10
10
  * ```ts
11
- * import {toTimestamp} from 'date-vir';
11
+ * import {toTimestamp, utcTimezone} from 'date-vir';
12
12
  *
13
13
  * const exampleDate: FullDate = {
14
14
  * year: 2024,
@@ -18,7 +18,7 @@ import { utcTimezone } from '../timezone/timezones.js';
18
18
  * minute: 1,
19
19
  * second: 1,
20
20
  * millisecond: 1,
21
- * timezone: 'UTC',
21
+ * timezone: utcTimezone,
22
22
  * };
23
23
  *
24
24
  * toTimestamp(exampleDate); // `1704416461001`
@@ -39,7 +39,7 @@ export function toTimestamp(fullDate) {
39
39
  * @example
40
40
  *
41
41
  * ```ts
42
- * import {toUtcIsoString} from 'date-vir';
42
+ * import {toUtcIsoString, utcTimezone} from 'date-vir';
43
43
  *
44
44
  * const exampleDate: FullDate = {
45
45
  * year: 2024,
@@ -49,7 +49,7 @@ export function toTimestamp(fullDate) {
49
49
  * minute: 1,
50
50
  * second: 1,
51
51
  * millisecond: 1,
52
- * timezone: 'UTC',
52
+ * timezone: utcTimezone,
53
53
  * };
54
54
  *
55
55
  * toUtcIsoString(exampleDate); // `'2024-01-05T01:01:01.001Z'`
@@ -105,7 +105,7 @@ dateLike) {
105
105
  * @example
106
106
  *
107
107
  * ```ts
108
- * import {toHttpDateString} from 'date-vir';
108
+ * import {toHttpDateString, utcTimezone} from 'date-vir';
109
109
  *
110
110
  * const exampleDate: FullDate = {
111
111
  * year: 2024,
@@ -115,7 +115,7 @@ dateLike) {
115
115
  * minute: 1,
116
116
  * second: 1,
117
117
  * millisecond: 1,
118
- * timezone: 'UTC',
118
+ * timezone: utcTimezone,
119
119
  * };
120
120
  *
121
121
  * toHttpDateString(exampleDate); // `'Fri, 05 Jan 2024 01:01:01 GMT'`
@@ -1,4 +1,4 @@
1
- import { type UtcTimezone } from '../timezone/timezones.js';
1
+ import { type Timezone, type UtcTimezone } from '../timezone/timezones.js';
2
2
  import { type DateLike } from './date-like.js';
3
3
  import { type FullDate } from './full-date-shape.js';
4
4
  /**
@@ -45,16 +45,16 @@ export declare function createUtcFullDate(dateLike: Readonly<DateLike>): FullDat
45
45
  * @example
46
46
  *
47
47
  * ```ts
48
- * import {createFullDate, timezones, utcTimezone} from 'date-vir';
48
+ * import {createFullDate, TimezoneName, utcTimezone} from 'date-vir';
49
49
  *
50
50
  * createFullDate('June 1, 2024', utcTimezone);
51
- * createFullDate(new Date(), timezones['Australia/Brisbane']);
52
- * createFullDate(112300120, timezones['Etc/GMT-11']);
51
+ * createFullDate(new Date(), TimezoneName['Australia/Brisbane']);
52
+ * createFullDate(112300120, TimezoneName['Etc/GMT-11']);
53
53
  * ```
54
54
  *
55
55
  * @throws Error: if a valid date cannot be created.
56
56
  */
57
- export declare function createFullDate<const SpecificTimezone extends string>(
57
+ export declare function createFullDate<const SpecificTimezone extends Timezone>(
58
58
  /** The original date representation to be converted into a FullDate. */
59
59
  dateLike: Readonly<DateLike>,
60
60
  /** The timezone that this date/time is meant for / originated from. */
@@ -67,7 +67,7 @@ timezone: SpecificTimezone): FullDate<SpecificTimezone>;
67
67
  * @example
68
68
  *
69
69
  * ```ts
70
- * import {toNewTimezone} from 'date-vir';
70
+ * import {toNewTimezone, TimezoneName, utcTimezone} from 'date-vir';
71
71
  *
72
72
  * const exampleDate: FullDate = {
73
73
  * year: 2024,
@@ -77,10 +77,10 @@ timezone: SpecificTimezone): FullDate<SpecificTimezone>;
77
77
  * minute: 1,
78
78
  * second: 1,
79
79
  * millisecond: 1,
80
- * timezone: 'UTC',
80
+ * timezone: utcTimezone,
81
81
  * };
82
82
  *
83
- * let result = toNewTimezone(exampleDate, timezones['Australia/Brisbane']);
83
+ * let result = toNewTimezone(exampleDate, TimezoneName['Australia/Brisbane']);
84
84
  * // output:
85
85
  * result = {
86
86
  * year: 2024,
@@ -90,8 +90,8 @@ timezone: SpecificTimezone): FullDate<SpecificTimezone>;
90
90
  * minute: 1,
91
91
  * second: 1,
92
92
  * millisecond: 1,
93
- * timezone: timezones['Australia/Brisbane'],
93
+ * timezone: TimezoneName['Australia/Brisbane'],
94
94
  * };
95
95
  * ```
96
96
  */
97
- export declare function toNewTimezone<const SpecificTimezone extends string>(fullDate: Readonly<FullDate>, timezone: SpecificTimezone): FullDate<SpecificTimezone>;
97
+ export declare function toNewTimezone<const SpecificTimezone extends Timezone>(fullDate: Readonly<FullDate>, timezone: SpecificTimezone): FullDate<SpecificTimezone>;
@@ -53,11 +53,11 @@ export function createUtcFullDate(dateLike) {
53
53
  * @example
54
54
  *
55
55
  * ```ts
56
- * import {createFullDate, timezones, utcTimezone} from 'date-vir';
56
+ * import {createFullDate, TimezoneName, utcTimezone} from 'date-vir';
57
57
  *
58
58
  * createFullDate('June 1, 2024', utcTimezone);
59
- * createFullDate(new Date(), timezones['Australia/Brisbane']);
60
- * createFullDate(112300120, timezones['Etc/GMT-11']);
59
+ * createFullDate(new Date(), TimezoneName['Australia/Brisbane']);
60
+ * createFullDate(112300120, TimezoneName['Etc/GMT-11']);
61
61
  * ```
62
62
  *
63
63
  * @throws Error: if a valid date cannot be created.
@@ -81,7 +81,7 @@ timezone) {
81
81
  * @example
82
82
  *
83
83
  * ```ts
84
- * import {toNewTimezone} from 'date-vir';
84
+ * import {toNewTimezone, TimezoneName, utcTimezone} from 'date-vir';
85
85
  *
86
86
  * const exampleDate: FullDate = {
87
87
  * year: 2024,
@@ -91,10 +91,10 @@ timezone) {
91
91
  * minute: 1,
92
92
  * second: 1,
93
93
  * millisecond: 1,
94
- * timezone: 'UTC',
94
+ * timezone: utcTimezone,
95
95
  * };
96
96
  *
97
- * let result = toNewTimezone(exampleDate, timezones['Australia/Brisbane']);
97
+ * let result = toNewTimezone(exampleDate, TimezoneName['Australia/Brisbane']);
98
98
  * // output:
99
99
  * result = {
100
100
  * year: 2024,
@@ -104,7 +104,7 @@ timezone) {
104
104
  * minute: 1,
105
105
  * second: 1,
106
106
  * millisecond: 1,
107
- * timezone: timezones['Australia/Brisbane'],
107
+ * timezone: TimezoneName['Australia/Brisbane'],
108
108
  * };
109
109
  * ```
110
110
  */
@@ -1,8 +1,9 @@
1
1
  import { type DateTime } from 'luxon';
2
+ import { type Timezone } from '../timezone/timezones.js';
2
3
  import { type FullDate } from './full-date-shape.js';
3
4
  /**
4
5
  * Types that can be converted into {@link FullDate} instances.
5
6
  *
6
7
  * @category Internal
7
8
  */
8
- export type DateLike<SpecificTimezone extends string = string> = string | Date | number | DateTime | FullDate<SpecificTimezone>;
9
+ export type DateLike<SpecificTimezone extends Timezone = Timezone> = string | Date | number | DateTime | FullDate<SpecificTimezone>;
@@ -1,6 +1,7 @@
1
1
  import { type Overwrite, type SetRequired } from '@augment-vir/common';
2
2
  import { type DayOfMonth, type Hour, type Minute, type MonthNumber, type Second } from '@date-vir/duration';
3
3
  import { type Simplify } from 'type-fest';
4
+ import { type Timezone } from '../timezone/timezones.js';
4
5
  /**
5
6
  * Time part of {@link FullDate} represented in a shape definition.
6
7
  *
@@ -16,14 +17,14 @@ export declare const timePartShape: import("object-shape-tester").Shape<{
16
17
  /** Millisecond of the second: 0-999 */
17
18
  millisecond: import("object-shape-tester").Shape<import("@sinclair/typebox").TUnsafe<number>>;
18
19
  /** The timezone that this date/time is meant for / originated from. */
19
- timezone: import("object-shape-tester").Shape<import("@sinclair/typebox").TUnsafe<string>>;
20
+ timezone: import("object-shape-tester").Shape<import("@sinclair/typebox").TUnsafe<Timezone>>;
20
21
  }>;
21
22
  /**
22
23
  * Time part of a {@link FullDate}.
23
24
  *
24
25
  * @category Internal
25
26
  */
26
- export type TimePart<SpecificTimezone extends string = string> = SetRequired<Partial<FullDate<SpecificTimezone>>, keyof (typeof timePartShape)['runtimeType']>;
27
+ export type TimePart<SpecificTimezone extends Timezone = Timezone> = SetRequired<Partial<FullDate<SpecificTimezone>>, keyof (typeof timePartShape)['runtimeType']>;
27
28
  /**
28
29
  * Date part of {@link FullDate} represented in a shape definition.
29
30
  *
@@ -41,14 +42,14 @@ export declare const datePartShape: import("object-shape-tester").Shape<{
41
42
  /** A day of the month: 1-31 depending on the month */
42
43
  day: import("object-shape-tester").Shape<import("@sinclair/typebox").TUnsafe<DayOfMonth>>;
43
44
  /** The timezone that this date/time is meant for / originated from. */
44
- timezone: import("object-shape-tester").Shape<import("@sinclair/typebox").TUnsafe<string>>;
45
+ timezone: import("object-shape-tester").Shape<import("@sinclair/typebox").TUnsafe<Timezone>>;
45
46
  }>;
46
47
  /**
47
48
  * Date part of {@link FullDate}.
48
49
  *
49
50
  * @category Internal
50
51
  */
51
- export type DatePart<SpecificTimezone extends string = string> = SetRequired<Partial<FullDate<SpecificTimezone>>, keyof (typeof datePartShape)['runtimeType']>;
52
+ export type DatePart<SpecificTimezone extends Timezone = Timezone> = SetRequired<Partial<FullDate<SpecificTimezone>>, keyof (typeof datePartShape)['runtimeType']>;
52
53
  /**
53
54
  * The complete {@link FullDate} represented in a shape definition.
54
55
  *
@@ -59,12 +60,12 @@ export declare const fullDateShape: import("object-shape-tester").Shape<import("
59
60
  minute: Minute;
60
61
  second: Minute;
61
62
  millisecond: number;
62
- timezone: string;
63
+ timezone: Timezone;
63
64
  } & {
64
65
  year: number;
65
66
  month: MonthNumber;
66
67
  day: DayOfMonth;
67
- timezone: string;
68
+ timezone: Timezone;
68
69
  }>>>;
69
70
  /**
70
71
  * A serializable object that completely specifies how any given date should be represented,
@@ -75,7 +76,7 @@ export declare const fullDateShape: import("object-shape-tester").Shape<import("
75
76
  * @example
76
77
  *
77
78
  * ```ts
78
- * import {FullDate, timezones} from 'date-vir';
79
+ * import {FullDate, TimezoneName} from 'date-vir';
79
80
  *
80
81
  * const myDate: FullDate = {
81
82
  * year: 2024,
@@ -87,11 +88,11 @@ export declare const fullDateShape: import("object-shape-tester").Shape<import("
87
88
  * second: 12,
88
89
  *
89
90
  * milliseconds: 94,
90
- * timezone: timezones['Australia/Brisbane'],
91
+ * timezone: TimezoneName['Australia/Brisbane'],
91
92
  * };
92
93
  * ```
93
94
  */
94
- export type FullDate<SpecificTimezone extends string = string> = Simplify<Overwrite<(typeof fullDateShape)['runtimeType'], {
95
+ export type FullDate<SpecificTimezone extends Timezone = Timezone> = Simplify<Overwrite<(typeof fullDateShape)['runtimeType'], {
95
96
  second: Second;
96
97
  timezone: SpecificTimezone;
97
98
  }>>;
@@ -1,3 +1,4 @@
1
+ import { type Timezone } from '../timezone/timezones.js';
1
2
  import { type FullDate } from './full-date-shape.js';
2
3
  /**
3
4
  * Asserts that the input is a valid {@link FullDate}.
@@ -17,4 +18,4 @@ export declare function isValidFullDate(input: unknown): input is FullDate;
17
18
  *
18
19
  * @category Assertion
19
20
  */
20
- export declare function hasTimezone<const SpecificTimezone extends string>(input: FullDate, timezone: SpecificTimezone): input is FullDate<SpecificTimezone>;
21
+ export declare function hasTimezone<const SpecificTimezone extends Timezone>(input: FullDate, timezone: SpecificTimezone): input is FullDate<SpecificTimezone>;
@@ -1,4 +1,5 @@
1
1
  import { DateTime } from 'luxon';
2
+ import { type Timezone } from '../timezone/timezones.js';
2
3
  import { type FullDate } from './full-date-shape.js';
3
4
  /**
4
5
  * Converts a {@link FullDate} object into a Luxon DateTime library. This is only needed if you need
@@ -15,4 +16,4 @@ export declare function toLuxonDateTime(fullDateInput: Readonly<FullDate>): Date
15
16
  *
16
17
  * @category Internal
17
18
  */
18
- export declare function parseLuxonDateTime<const SpecificTimezone extends string>(dateTimeInput: Readonly<DateTime>, forcedTimezone?: SpecificTimezone): FullDate<SpecificTimezone>;
19
+ export declare function parseLuxonDateTime<const SpecificTimezone extends Timezone>(dateTimeInput: Readonly<DateTime>, forcedTimezone?: SpecificTimezone): FullDate<SpecificTimezone>;
@@ -1,4 +1,4 @@
1
- import { omitObjectKeys } from '@augment-vir/common';
1
+ import { applyBrand, omitObjectKeys } from '@augment-vir/common';
2
2
  import { assertWrapDayOfMonth, assertWrapHour, assertWrapMillisecond, assertWrapMinute, assertWrapMonthNumber, assertWrapSecond, } from '@date-vir/duration';
3
3
  import { DateTime } from 'luxon';
4
4
  /**
@@ -30,6 +30,11 @@ export function parseLuxonDateTime(dateTimeInput, forcedTimezone) {
30
30
  if (!dateTimeInput.isValid) {
31
31
  throw new Error(`Invalid input: '${dateTimeInput.toISO()}'`);
32
32
  }
33
+ const zoneName = dateTimeInput.zoneName;
34
+ if (zoneName == undefined) {
35
+ throw new Error('Valid Luxon dates must have a timezone.');
36
+ }
37
+ const brandedZoneName = applyBrand(zoneName);
33
38
  return {
34
39
  day: assertWrapDayOfMonth(dateTimeInput.day),
35
40
  month: assertWrapMonthNumber(dateTimeInput.month),
@@ -38,6 +43,6 @@ export function parseLuxonDateTime(dateTimeInput, forcedTimezone) {
38
43
  minute: assertWrapMinute(dateTimeInput.minute),
39
44
  second: assertWrapSecond(dateTimeInput.second),
40
45
  millisecond: assertWrapMillisecond(dateTimeInput.millisecond),
41
- timezone: forcedTimezone ?? dateTimeInput.zoneName,
46
+ timezone: forcedTimezone ?? brandedZoneName,
42
47
  };
43
48
  }
@@ -1,3 +1,4 @@
1
+ import { type Timezone } from '../timezone/timezones.js';
1
2
  import { type DateLike } from './date-like.js';
2
3
  import { type FullDate } from './full-date-shape.js';
3
4
  /**
@@ -5,7 +6,7 @@ import { type FullDate } from './full-date-shape.js';
5
6
  * timezone. If the conversion fails or the input {@link DateLike} is empty, `undefined` is
6
7
  * returned.
7
8
  */
8
- export declare function maybeCreateFullDate<const SpecificTimezone extends string>(
9
+ export declare function maybeCreateFullDate<const SpecificTimezone extends Timezone>(
9
10
  /** The original date representation to be converted into a FullDate. */
10
11
  dateLike: Readonly<DateLike> | undefined | null,
11
12
  /** The timezone that this date/time is meant for / originated from. */
@@ -1,3 +1,4 @@
1
+ import { type Timezone } from '../timezone/timezones.js';
1
2
  import { type FullDate } from './full-date-shape.js';
2
3
  /**
3
4
  * Parses any date string into a {@link FullDate} using the specified pattern and timezone. Prefer
@@ -11,7 +12,7 @@ import { type FullDate } from './full-date-shape.js';
11
12
  *
12
13
  * @category FullDate
13
14
  */
14
- export declare function parseDateStringWithPattern<const SpecificTimezone extends string>({ dateString, formatString, timezone, }: {
15
+ export declare function parseDateStringWithPattern<const SpecificTimezone extends Timezone>({ dateString, formatString, timezone, }: {
15
16
  /** The date string to be parsed. */
16
17
  dateString: string;
17
18
  /**
@@ -29,4 +30,4 @@ export declare function parseDateStringWithPattern<const SpecificTimezone extend
29
30
  * @category FullDate
30
31
  * @category HTML
31
32
  */
32
- export declare function parseInputElementValue<const SpecificTimezone extends string>(elementOrValue: Readonly<Pick<HTMLInputElement, 'value'>> | string | null | undefined, timezone: SpecificTimezone): FullDate<SpecificTimezone> | undefined;
33
+ export declare function parseInputElementValue<const SpecificTimezone extends Timezone>(elementOrValue: Readonly<Pick<HTMLInputElement, 'value'>> | string | null | undefined, timezone: SpecificTimezone): FullDate<SpecificTimezone> | undefined;
@@ -1,8 +1,9 @@
1
1
  import { DateTime } from 'luxon';
2
+ import { type Timezone } from '../timezone/timezones.js';
2
3
  /**
3
4
  * Tries extra known formats for parsing date strings, even those that browsers do not natively
4
5
  * support.
5
6
  *
6
7
  * @category Internal
7
8
  */
8
- export declare function parseDateString(dateString: string, timezone: string): DateTime | undefined;
9
+ export declare function parseDateString(dateString: string, timezone: Timezone): DateTime | undefined;
@@ -1,4 +1,3 @@
1
- /* eslint-disable @virmator/prefer-params-object */
2
1
  import { DateTime } from 'luxon';
3
2
  /**
4
3
  * These formats are for luxon, documented here:
@@ -1,3 +1,4 @@
1
+ import { type Timezone } from './timezones.js';
1
2
  /**
2
3
  * Checks that the given timezone is valid.
3
4
  *
@@ -7,7 +8,7 @@
7
8
  *
8
9
  * @category Assertion
9
10
  */
10
- export declare function isValidTimezone(potentialTimezone: string): boolean;
11
+ export declare function isValidTimezone(raw: string): raw is Timezone;
11
12
  /**
12
13
  * Asserts that the given input is a valid timezone name.
13
14
  *
@@ -17,4 +18,16 @@ export declare function isValidTimezone(potentialTimezone: string): boolean;
17
18
  *
18
19
  * @category Assertion
19
20
  */
20
- export declare function assertValidTimezone(potentialTimezone: string, userMessage?: string | undefined): void;
21
+ export declare function assertValidTimezone(raw: string, userMessage?: string | undefined): asserts raw is Timezone;
22
+ /**
23
+ * Asserts that the given input is a valid timezone name and returns it.
24
+ *
25
+ * @category Assertion
26
+ */
27
+ export declare function assertWrapValidTimezone(raw: string, userMessage?: string | undefined): Timezone;
28
+ /**
29
+ * Checks that the given input is a valid timezone name and returns it when valid.
30
+ *
31
+ * @category Assertion
32
+ */
33
+ export declare function checkWrapValidTimezone(raw: string): Timezone | undefined;
@@ -19,16 +19,16 @@ const ianaValidityCache = new Map();
19
19
  *
20
20
  * @category Assertion
21
21
  */
22
- export function isValidTimezone(potentialTimezone) {
23
- if (knownTimezones.has(potentialTimezone)) {
22
+ export function isValidTimezone(raw) {
23
+ if (knownTimezones.has(raw)) {
24
24
  return true;
25
25
  }
26
- const cached = ianaValidityCache.get(potentialTimezone);
26
+ const cached = ianaValidityCache.get(raw);
27
27
  if (cached != undefined) {
28
28
  return cached;
29
29
  }
30
- const isValid = Info.isValidIANAZone(potentialTimezone);
31
- ianaValidityCache.set(potentialTimezone, isValid);
30
+ const isValid = Info.isValidIANAZone(raw);
31
+ ianaValidityCache.set(raw, isValid);
32
32
  return isValid;
33
33
  }
34
34
  /**
@@ -40,8 +40,25 @@ export function isValidTimezone(potentialTimezone) {
40
40
  *
41
41
  * @category Assertion
42
42
  */
43
- export function assertValidTimezone(potentialTimezone, userMessage) {
44
- if (!isValidTimezone(potentialTimezone)) {
45
- throw new AssertionError(`'${potentialTimezone}' is not a valid time zone`, userMessage);
43
+ export function assertValidTimezone(raw, userMessage) {
44
+ if (!isValidTimezone(raw)) {
45
+ throw new AssertionError(`'${raw}' is not a valid time zone`, userMessage);
46
46
  }
47
47
  }
48
+ /**
49
+ * Asserts that the given input is a valid timezone name and returns it.
50
+ *
51
+ * @category Assertion
52
+ */
53
+ export function assertWrapValidTimezone(raw, userMessage) {
54
+ assertValidTimezone(raw, userMessage);
55
+ return raw;
56
+ }
57
+ /**
58
+ * Checks that the given input is a valid timezone name and returns it when valid.
59
+ *
60
+ * @category Assertion
61
+ */
62
+ export function checkWrapValidTimezone(raw) {
63
+ return isValidTimezone(raw) ? raw : undefined;
64
+ }
@@ -1,12 +1,13 @@
1
+ import { type Timezone } from './timezones.js';
1
2
  /**
2
3
  * A shape for a timezone value.
3
4
  *
4
5
  * Unlike a strict enum check against the typed {@link Timezone} list, this validates at runtime via
5
6
  * {@link isValidTimezone} (i.e. any valid IANA zone name). It therefore accepts valid IANA names
6
7
  * that aren't in the typed list, such as legacy aliases like `'America/Indianapolis'` that some
7
- * environments (notably Safari) still report from `Intl`. The static type is `string` so that
8
- * timezone inputs are not restricted to the {@link Timezone} enum.
8
+ * environments (notably Safari) still report from `Intl`. The branded {@link Timezone} type allows
9
+ * timezone inputs that are not restricted to the {@link Timezone} list.
9
10
  *
10
11
  * @category Shape
11
12
  */
12
- export declare const timezoneShape: (defaultValue?: string | undefined) => import("object-shape-tester").Shape<import("@sinclair/typebox").TUnsafe<string>>;
13
+ export declare const timezoneShape: (defaultValue?: Timezone | undefined) => import("object-shape-tester").Shape<import("@sinclair/typebox").TUnsafe<Timezone>>;
@@ -8,8 +8,8 @@ import { utcTimezone } from './timezones.js';
8
8
  * Unlike a strict enum check against the typed {@link Timezone} list, this validates at runtime via
9
9
  * {@link isValidTimezone} (i.e. any valid IANA zone name). It therefore accepts valid IANA names
10
10
  * that aren't in the typed list, such as legacy aliases like `'America/Indianapolis'` that some
11
- * environments (notably Safari) still report from `Intl`. The static type is `string` so that
12
- * timezone inputs are not restricted to the {@link Timezone} enum.
11
+ * environments (notably Safari) still report from `Intl`. The branded {@link Timezone} type allows
12
+ * timezone inputs that are not restricted to the {@link Timezone} list.
13
13
  *
14
14
  * @category Shape
15
15
  */
@@ -1,12 +1,25 @@
1
- import { type ArrayElement } from '@augment-vir/common';
1
+ import { type ArrayElement, type Branded } from '@augment-vir/common';
2
2
  import { allTimezoneNames } from './timezone-names.js';
3
3
  /**
4
- * All possible timezone names.
4
+ * All known timezone names.
5
5
  *
6
6
  * @category Timezone
7
7
  * @see {@link allTimezoneNames}
8
8
  */
9
- export type Timezone = ArrayElement<typeof allTimezoneNames>;
9
+ export type TimezoneName = ArrayElement<typeof allTimezoneNames>;
10
+ /**
11
+ * A branded string for any timezone
12
+ *
13
+ * @category Timezone
14
+ * @see {@link allTimezoneNames}
15
+ */
16
+ export type TimezoneString = Branded<string, 'timezone-string'>;
17
+ /**
18
+ * Any known or unknown timezone.
19
+ *
20
+ * @category Timezone
21
+ */
22
+ export type Timezone = TimezoneString | TimezoneName;
10
23
  /**
11
24
  * An enum of all possible timezone names.
12
25
  *
@@ -14,20 +27,20 @@ export type Timezone = ArrayElement<typeof allTimezoneNames>;
14
27
  * @example
15
28
  *
16
29
  * ```ts
17
- * import {Timezone} from 'date-vir';
30
+ * import {TimezoneName} from 'date-vir';
18
31
  *
19
- * Timezone['Africa/Bamako'];
32
+ * TimezoneName['Africa/Bamako'];
20
33
  * ```
21
34
  */
22
- export declare const Timezone: Readonly<{
23
- [SpecificTimezoneName in Timezone]: SpecificTimezoneName;
35
+ export declare const TimezoneName: Readonly<{
36
+ [SpecificTimezoneName in TimezoneName]: SpecificTimezoneName;
24
37
  }>;
25
38
  /**
26
39
  * The timezone of the current user's environment.
27
40
  *
28
41
  * @category Timezone
29
42
  */
30
- export declare const userTimezone: string;
43
+ export declare const userTimezone: NoInfer<TimezoneString>;
31
44
  /**
32
45
  * The UTC timezone.
33
46
  *
@@ -1,3 +1,4 @@
1
+ import { applyBrand } from '@augment-vir/common';
1
2
  import { Settings } from 'luxon';
2
3
  import { allTimezoneNames } from './timezone-names.js';
3
4
  /**
@@ -7,12 +8,12 @@ import { allTimezoneNames } from './timezone-names.js';
7
8
  * @example
8
9
  *
9
10
  * ```ts
10
- * import {Timezone} from 'date-vir';
11
+ * import {TimezoneName} from 'date-vir';
11
12
  *
12
- * Timezone['Africa/Bamako'];
13
+ * TimezoneName['Africa/Bamako'];
13
14
  * ```
14
15
  */
15
- export const Timezone = allTimezoneNames.reduce((accum, timezoneName) => {
16
+ export const TimezoneName = allTimezoneNames.reduce((accum, timezoneName) => {
16
17
  accum[timezoneName] = timezoneName;
17
18
  return accum;
18
19
  }, {});
@@ -21,10 +22,10 @@ export const Timezone = allTimezoneNames.reduce((accum, timezoneName) => {
21
22
  *
22
23
  * @category Timezone
23
24
  */
24
- export const userTimezone = Settings.defaultZone.name;
25
+ export const userTimezone = applyBrand(Settings.defaultZone.name);
25
26
  /**
26
27
  * The UTC timezone.
27
28
  *
28
29
  * @category Timezone
29
30
  */
30
- export const utcTimezone = Timezone.UTC;
31
+ export const utcTimezone = TimezoneName.UTC;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "date-vir",
3
- "version": "8.6.2",
3
+ "version": "8.6.3",
4
4
  "description": "Easy and explicit dates and times.",
5
5
  "keywords": [
6
6
  "date",
@@ -22,6 +22,7 @@
22
22
  "name": "electrovir",
23
23
  "url": "https://github.com/electrovir"
24
24
  },
25
+ "sideEffects": false,
25
26
  "type": "module",
26
27
  "main": "dist/index.js",
27
28
  "module": "dist/index.js",
@@ -34,25 +35,25 @@
34
35
  "test:docs": "virmator docs check"
35
36
  },
36
37
  "dependencies": {
37
- "@augment-vir/assert": "^32.0.0",
38
- "@augment-vir/common": "^32.0.0",
39
- "@date-vir/duration": "^8.6.2",
40
- "@types/luxon": "^3.7.2",
38
+ "@augment-vir/assert": "^32.2.1",
39
+ "@augment-vir/common": "^32.2.1",
40
+ "@date-vir/duration": "^8.6.3",
41
+ "@types/luxon": "^3.7.3",
41
42
  "luxon": "^3.7.2",
42
- "object-shape-tester": "^6.14.0",
43
- "type-fest": "^5.7.0"
43
+ "object-shape-tester": "^6.14.1",
44
+ "type-fest": "^5.8.0"
44
45
  },
45
46
  "devDependencies": {
46
- "@augment-vir/test": "^32.0.0",
47
- "@web/dev-server-esbuild": "^1.0.5",
48
- "@web/test-runner": "^0.20.2",
49
- "@web/test-runner-commands": "^0.9.0",
50
- "@web/test-runner-playwright": "^0.11.1",
51
- "@web/test-runner-visual-regression": "^0.10.0",
52
- "element-vir": "^26.17.0",
47
+ "@augment-vir/test": "^32.2.1",
48
+ "@web/dev-server-esbuild": "^2.0.0",
49
+ "@web/test-runner": "^1.0.0",
50
+ "@web/test-runner-commands": "^1.0.1",
51
+ "@web/test-runner-playwright": "^1.0.0",
52
+ "@web/test-runner-visual-regression": "^1.0.1",
53
+ "element-vir": "^26.17.3",
53
54
  "istanbul-smart-text-reporter": "^1.1.5",
54
55
  "markdown-code-example-inserter": "^3.0.6",
55
- "typedoc": "^0.28.19",
56
+ "typedoc": "^0.28.20",
56
57
  "typescript": "^6.0.3"
57
58
  },
58
59
  "engines": {