@trackunit/date-and-time-utils 1.19.0 → 1.19.1-alpha-d660d5dfec1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/index.cjs.js +36 -0
- package/index.esm.js +36 -0
- package/migrations/entry.js.map +1 -0
- package/package.json +1 -1
- package/src/systemTimeZone.d.ts +9 -0
- package/src/temporal.d.ts +1 -0
package/README.md
CHANGED
|
@@ -10,6 +10,12 @@ AI agents should use the machine-readable index at [`/llms.txt`](https://design.
|
|
|
10
10
|
|
|
11
11
|
For more info and a full guide on Iris App SDK Development, please visit our [Developer Hub](https://developers.trackunit.com/).
|
|
12
12
|
|
|
13
|
+
## System time zone fallback
|
|
14
|
+
|
|
15
|
+
Importing this package patches `Intl.DateTimeFormat.prototype.resolvedOptions` for the whole page. Some browsers report the system `timeZone` as `undefined` when they can't map the OS time zone to an IANA id (for example Chrome on Windows with "British Columbia Standard Time"), which makes the Temporal polyfill throw. The patch fills in the `Etc/GMT` zone for the system's current whole-hour UTC offset (UTC-07:00 becomes `Etc/GMT+7`), or `UTC` otherwise.
|
|
16
|
+
|
|
17
|
+
Browsers that resolve a time zone, explicitly requested time zones and server runtimes are unaffected.
|
|
18
|
+
|
|
13
19
|
## Trackunit
|
|
14
20
|
|
|
15
21
|
This package was developed by Trackunit ApS.
|
package/index.cjs.js
CHANGED
|
@@ -2,6 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
var polyfill = require('@js-temporal/polyfill');
|
|
4
4
|
|
|
5
|
+
const UTC_TIME_ZONE_ID = "UTC";
|
|
6
|
+
/**
|
|
7
|
+
* Returns the `Etc/GMT` time zone matching the system's current UTC offset, or `UTC` when the
|
|
8
|
+
* offset isn't a whole number of hours. Offset ids like `-07:00` aren't used because the Temporal
|
|
9
|
+
* polyfill can't format dates in them.
|
|
10
|
+
*/
|
|
11
|
+
const getSystemOffsetTimeZoneId = () => {
|
|
12
|
+
const offsetHours = -new Date().getTimezoneOffset() / 60;
|
|
13
|
+
// Etc/GMT zones only exist from UTC-12 to UTC+14.
|
|
14
|
+
if (offsetHours === 0 || !Number.isInteger(offsetHours) || offsetHours < -12 || offsetHours > 14) {
|
|
15
|
+
return UTC_TIME_ZONE_ID;
|
|
16
|
+
}
|
|
17
|
+
// Etc/GMT ids use the POSIX sign convention, so UTC-07:00 is Etc/GMT+7.
|
|
18
|
+
return `Etc/GMT${offsetHours > 0 ? "-" : "+"}${Math.abs(offsetHours)}`;
|
|
19
|
+
};
|
|
20
|
+
const SYSTEM_TIME_ZONE_FALLBACK = Symbol.for("@trackunit/date-and-time-utils/system-time-zone-fallback");
|
|
21
|
+
const nativeResolvedOptions = Intl.DateTimeFormat.prototype.resolvedOptions;
|
|
22
|
+
/**
|
|
23
|
+
* Browsers resolve `timeZone` to `undefined` when they can't map the OS time zone to an IANA id
|
|
24
|
+
* (e.g. Chrome with the Windows "British Columbia Standard Time" zone). The Temporal polyfill reads
|
|
25
|
+
* it for `Temporal.Now` and for formatting, and throws on `undefined`, so fill in a fallback zone.
|
|
26
|
+
* Skipped when another copy of this library already installed it.
|
|
27
|
+
*/
|
|
28
|
+
if (!(SYSTEM_TIME_ZONE_FALLBACK in nativeResolvedOptions)) {
|
|
29
|
+
Intl.DateTimeFormat.prototype.resolvedOptions = Object.assign(function resolvedOptions() {
|
|
30
|
+
const options = nativeResolvedOptions.call(this);
|
|
31
|
+
if (!options.timeZone) {
|
|
32
|
+
options.timeZone = getSystemOffsetTimeZoneId();
|
|
33
|
+
}
|
|
34
|
+
return options;
|
|
35
|
+
}, { [SYSTEM_TIME_ZONE_FALLBACK]: true });
|
|
36
|
+
}
|
|
37
|
+
|
|
5
38
|
/**
|
|
6
39
|
* converts timZoneId to TimeZone object with default to current user timezone
|
|
7
40
|
*
|
|
@@ -128,10 +161,12 @@ const getHourCycle = (locale, hourCycleOverride) => {
|
|
|
128
161
|
const formatDateUtil = (date, format, timeZone, locale, hourCycleOverride) => {
|
|
129
162
|
const hourCycle = getHourCycle(locale, hourCycleOverride);
|
|
130
163
|
const dateObj = timeZone ? toZonedDateTimeUtil(date, timeZone) : toTemporalUtil(toDateUtil(date));
|
|
164
|
+
// Plain values are formatted in UTC, so the output doesn't depend on the browser's system time zone.
|
|
131
165
|
if (format?.selectFormat === "dateOnly") {
|
|
132
166
|
if (dateObj instanceof polyfill.Temporal.ZonedDateTime) {
|
|
133
167
|
return dateObj.toPlainDate().toLocaleString(locale, {
|
|
134
168
|
dateStyle: format.dateFormat ?? "medium",
|
|
169
|
+
timeZone: "UTC",
|
|
135
170
|
});
|
|
136
171
|
}
|
|
137
172
|
return dateObj.toLocaleString(locale, {
|
|
@@ -144,6 +179,7 @@ const formatDateUtil = (date, format, timeZone, locale, hourCycleOverride) => {
|
|
|
144
179
|
return dateObj.toPlainTime().toLocaleString(locale, {
|
|
145
180
|
timeStyle: format.timeFormat ?? "short",
|
|
146
181
|
hourCycle,
|
|
182
|
+
timeZone: "UTC",
|
|
147
183
|
});
|
|
148
184
|
}
|
|
149
185
|
return dateObj.toLocaleString(locale, {
|
package/index.esm.js
CHANGED
|
@@ -1,6 +1,39 @@
|
|
|
1
1
|
import { Temporal } from '@js-temporal/polyfill';
|
|
2
2
|
export { Temporal } from '@js-temporal/polyfill';
|
|
3
3
|
|
|
4
|
+
const UTC_TIME_ZONE_ID = "UTC";
|
|
5
|
+
/**
|
|
6
|
+
* Returns the `Etc/GMT` time zone matching the system's current UTC offset, or `UTC` when the
|
|
7
|
+
* offset isn't a whole number of hours. Offset ids like `-07:00` aren't used because the Temporal
|
|
8
|
+
* polyfill can't format dates in them.
|
|
9
|
+
*/
|
|
10
|
+
const getSystemOffsetTimeZoneId = () => {
|
|
11
|
+
const offsetHours = -new Date().getTimezoneOffset() / 60;
|
|
12
|
+
// Etc/GMT zones only exist from UTC-12 to UTC+14.
|
|
13
|
+
if (offsetHours === 0 || !Number.isInteger(offsetHours) || offsetHours < -12 || offsetHours > 14) {
|
|
14
|
+
return UTC_TIME_ZONE_ID;
|
|
15
|
+
}
|
|
16
|
+
// Etc/GMT ids use the POSIX sign convention, so UTC-07:00 is Etc/GMT+7.
|
|
17
|
+
return `Etc/GMT${offsetHours > 0 ? "-" : "+"}${Math.abs(offsetHours)}`;
|
|
18
|
+
};
|
|
19
|
+
const SYSTEM_TIME_ZONE_FALLBACK = Symbol.for("@trackunit/date-and-time-utils/system-time-zone-fallback");
|
|
20
|
+
const nativeResolvedOptions = Intl.DateTimeFormat.prototype.resolvedOptions;
|
|
21
|
+
/**
|
|
22
|
+
* Browsers resolve `timeZone` to `undefined` when they can't map the OS time zone to an IANA id
|
|
23
|
+
* (e.g. Chrome with the Windows "British Columbia Standard Time" zone). The Temporal polyfill reads
|
|
24
|
+
* it for `Temporal.Now` and for formatting, and throws on `undefined`, so fill in a fallback zone.
|
|
25
|
+
* Skipped when another copy of this library already installed it.
|
|
26
|
+
*/
|
|
27
|
+
if (!(SYSTEM_TIME_ZONE_FALLBACK in nativeResolvedOptions)) {
|
|
28
|
+
Intl.DateTimeFormat.prototype.resolvedOptions = Object.assign(function resolvedOptions() {
|
|
29
|
+
const options = nativeResolvedOptions.call(this);
|
|
30
|
+
if (!options.timeZone) {
|
|
31
|
+
options.timeZone = getSystemOffsetTimeZoneId();
|
|
32
|
+
}
|
|
33
|
+
return options;
|
|
34
|
+
}, { [SYSTEM_TIME_ZONE_FALLBACK]: true });
|
|
35
|
+
}
|
|
36
|
+
|
|
4
37
|
/**
|
|
5
38
|
* converts timZoneId to TimeZone object with default to current user timezone
|
|
6
39
|
*
|
|
@@ -127,10 +160,12 @@ const getHourCycle = (locale, hourCycleOverride) => {
|
|
|
127
160
|
const formatDateUtil = (date, format, timeZone, locale, hourCycleOverride) => {
|
|
128
161
|
const hourCycle = getHourCycle(locale, hourCycleOverride);
|
|
129
162
|
const dateObj = timeZone ? toZonedDateTimeUtil(date, timeZone) : toTemporalUtil(toDateUtil(date));
|
|
163
|
+
// Plain values are formatted in UTC, so the output doesn't depend on the browser's system time zone.
|
|
130
164
|
if (format?.selectFormat === "dateOnly") {
|
|
131
165
|
if (dateObj instanceof Temporal.ZonedDateTime) {
|
|
132
166
|
return dateObj.toPlainDate().toLocaleString(locale, {
|
|
133
167
|
dateStyle: format.dateFormat ?? "medium",
|
|
168
|
+
timeZone: "UTC",
|
|
134
169
|
});
|
|
135
170
|
}
|
|
136
171
|
return dateObj.toLocaleString(locale, {
|
|
@@ -143,6 +178,7 @@ const formatDateUtil = (date, format, timeZone, locale, hourCycleOverride) => {
|
|
|
143
178
|
return dateObj.toPlainTime().toLocaleString(locale, {
|
|
144
179
|
timeStyle: format.timeFormat ?? "short",
|
|
145
180
|
hourCycle,
|
|
181
|
+
timeZone: "UTC",
|
|
146
182
|
});
|
|
147
183
|
}
|
|
148
184
|
return dateObj.toLocaleString(locale, {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../../../libs/date-and-time/utils/migrations/entry.ts"],"names":[],"mappings":"","sourcesContent":["export {};\n"]}
|
package/package.json
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
declare const UTC_TIME_ZONE_ID = "UTC";
|
|
2
|
+
/**
|
|
3
|
+
* Returns the `Etc/GMT` time zone matching the system's current UTC offset, or `UTC` when the
|
|
4
|
+
* offset isn't a whole number of hours. Offset ids like `-07:00` aren't used because the Temporal
|
|
5
|
+
* polyfill can't format dates in them.
|
|
6
|
+
*/
|
|
7
|
+
declare const getSystemOffsetTimeZoneId: () => string;
|
|
8
|
+
declare const SYSTEM_TIME_ZONE_FALLBACK: unique symbol;
|
|
9
|
+
declare const nativeResolvedOptions: () => Intl.ResolvedDateTimeFormatOptions;
|
package/src/temporal.d.ts
CHANGED