summaryrefslogtreecommitdiffstats
path: root/src/modules/dayjs/plugin/timezone
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/dayjs/plugin/timezone')
-rw-r--r--src/modules/dayjs/plugin/timezone/index.d.ts20
-rw-r--r--src/modules/dayjs/plugin/timezone/index.js188
2 files changed, 208 insertions, 0 deletions
diff --git a/src/modules/dayjs/plugin/timezone/index.d.ts b/src/modules/dayjs/plugin/timezone/index.d.ts
new file mode 100644
index 0000000..8d90359
--- /dev/null
+++ b/src/modules/dayjs/plugin/timezone/index.d.ts
@@ -0,0 +1,20 @@
+import { PluginFunc, ConfigType } from 'dayjs/esm'
+
+declare const plugin: PluginFunc
+export = plugin
+
+declare module 'dayjs/esm' {
+ interface Dayjs {
+ tz(timezone?: string, keepLocalTime?: boolean): Dayjs
+ offsetName(type?: 'short' | 'long'): string | undefined
+ }
+
+ interface DayjsTimezone {
+ (date: ConfigType, timezone?: string): Dayjs
+ (date: ConfigType, format: string, timezone?: string): Dayjs
+ guess(): string
+ setDefault(timezone?: string): void
+ }
+
+ const tz: DayjsTimezone
+}
diff --git a/src/modules/dayjs/plugin/timezone/index.js b/src/modules/dayjs/plugin/timezone/index.js
new file mode 100644
index 0000000..a7bd673
--- /dev/null
+++ b/src/modules/dayjs/plugin/timezone/index.js
@@ -0,0 +1,188 @@
+/**
+ * Copy from node_modules/dayjs/plugin/timezone.js
+ * Try to fix https://github.com/louislam/uptime-kuma/issues/2318
+ * Source: https://github.com/iamkun/dayjs/tree/dev/src/plugin/utc
+ * License: MIT
+ */
+import { MIN, MS } from "../../constant";
+let typeToPos = {
+ year: 0,
+ month: 1,
+ day: 2,
+ hour: 3,
+ minute: 4,
+ second: 5
+}; // Cache time-zone lookups from Intl.DateTimeFormat,
+// as it is a *very* slow method.
+
+let dtfCache = {};
+
+let getDateTimeFormat = function getDateTimeFormat(timezone, options) {
+ if (options === void 0) {
+ options = {};
+ }
+
+ let timeZoneName = options.timeZoneName || "short";
+ let key = timezone + "|" + timeZoneName;
+ let dtf = dtfCache[key];
+
+ if (!dtf) {
+ dtf = new Intl.DateTimeFormat("en-US", {
+ hour12: false,
+ timeZone: timezone,
+ year: "numeric",
+ month: "2-digit",
+ day: "2-digit",
+ hour: "2-digit",
+ minute: "2-digit",
+ second: "2-digit",
+ timeZoneName: timeZoneName
+ });
+ dtfCache[key] = dtf;
+ }
+
+ return dtf;
+};
+
+export default (function (o, c, d) {
+ let defaultTimezone;
+
+ let makeFormatParts = function makeFormatParts(timestamp, timezone, options) {
+ if (options === void 0) {
+ options = {};
+ }
+
+ let date = new Date(timestamp);
+ let dtf = getDateTimeFormat(timezone, options);
+ return dtf.formatToParts(date);
+ };
+
+ let tzOffset = function tzOffset(timestamp, timezone) {
+ let formatResult = makeFormatParts(timestamp, timezone);
+ let filled = [];
+
+ for (let i = 0; i < formatResult.length; i += 1) {
+ let _formatResult$i = formatResult[i];
+ let type = _formatResult$i.type;
+ let value = _formatResult$i.value;
+ let pos = typeToPos[type];
+
+ if (pos >= 0) {
+ filled[pos] = parseInt(value, 10);
+ }
+ }
+
+ let hour = filled[3]; // Workaround for the same behavior in different node version
+ // https://github.com/nodejs/node/issues/33027
+
+ /* istanbul ignore next */
+
+ let fixedHour = hour === 24 ? 0 : hour;
+ let utcString = filled[0] + "-" + filled[1] + "-" + filled[2] + " " + fixedHour + ":" + filled[4] + ":" + filled[5] + ":000";
+ let utcTs = d.utc(utcString).valueOf();
+ let asTS = +timestamp;
+ let over = asTS % 1000;
+ asTS -= over;
+ return (utcTs - asTS) / (60 * 1000);
+ }; // find the right offset a given local time. The o input is our guess, which determines which
+ // offset we'll pick in ambiguous cases (e.g. there are two 3 AMs b/c Fallback DST)
+ // https://github.com/moment/luxon/blob/master/src/datetime.js#L76
+
+ let fixOffset = function fixOffset(localTS, o0, tz) {
+ // Our UTC time is just a guess because our offset is just a guess
+ let utcGuess = localTS - o0 * 60 * 1000; // Test whether the zone matches the offset for this ts
+
+ let o2 = tzOffset(utcGuess, tz); // If so, offset didn't change and we're done
+
+ if (o0 === o2) {
+ return [ utcGuess, o0 ];
+ } // If not, change the ts by the difference in the offset
+
+ utcGuess -= (o2 - o0) * 60 * 1000; // If that gives us the local time we want, we're done
+
+ let o3 = tzOffset(utcGuess, tz);
+
+ if (o2 === o3) {
+ return [ utcGuess, o2 ];
+ } // If it's different, we're in a hole time.
+ // The offset has changed, but the we don't adjust the time
+
+ return [ localTS - Math.min(o2, o3) * 60 * 1000, Math.max(o2, o3) ];
+ };
+
+ let proto = c.prototype;
+
+ proto.tz = function (timezone, keepLocalTime) {
+ if (timezone === void 0) {
+ timezone = defaultTimezone;
+ }
+
+ let oldOffset = this.utcOffset();
+ let date = this.toDate();
+ let target = date.toLocaleString("en-US", {
+ timeZone: timezone
+ }).replace("\u202f", " ");
+ let diff = Math.round((date - new Date(target)) / 1000 / 60);
+ let ins = d(target).$set(MS, this.$ms).utcOffset(-Math.round(date.getTimezoneOffset() / 15) * 15 - diff, true);
+
+ if (keepLocalTime) {
+ let newOffset = ins.utcOffset();
+ ins = ins.add(oldOffset - newOffset, MIN);
+ }
+
+ ins.$x.$timezone = timezone;
+ return ins;
+ };
+
+ proto.offsetName = function (type) {
+ // type: short(default) / long
+ let zone = this.$x.$timezone || d.tz.guess();
+ let result = makeFormatParts(this.valueOf(), zone, {
+ timeZoneName: type
+ }).find(function (m) {
+ return m.type.toLowerCase() === "timezonename";
+ });
+ return result && result.value;
+ };
+
+ let oldStartOf = proto.startOf;
+
+ proto.startOf = function (units, startOf) {
+ if (!this.$x || !this.$x.$timezone) {
+ return oldStartOf.call(this, units, startOf);
+ }
+
+ let withoutTz = d(this.format("YYYY-MM-DD HH:mm:ss:SSS"));
+ let startOfWithoutTz = oldStartOf.call(withoutTz, units, startOf);
+ return startOfWithoutTz.tz(this.$x.$timezone, true);
+ };
+
+ d.tz = function (input, arg1, arg2) {
+ let parseFormat = arg2 && arg1;
+ let timezone = arg2 || arg1 || defaultTimezone;
+ let previousOffset = tzOffset(+d(), timezone);
+
+ if (typeof input !== "string") {
+ // timestamp number || js Date || Day.js
+ return d(input).tz(timezone);
+ }
+
+ let localTs = d.utc(input, parseFormat).valueOf();
+
+ let _fixOffset = fixOffset(localTs, previousOffset, timezone);
+ let targetTs = _fixOffset[0];
+ let targetOffset = _fixOffset[1];
+
+ let ins = d(targetTs).utcOffset(targetOffset);
+ ins.$x.$timezone = timezone;
+ return ins;
+ };
+
+ d.tz.guess = function () {
+ return Intl.DateTimeFormat().resolvedOptions().timeZone;
+ };
+
+ d.tz.setDefault = function (timezone) {
+ defaultTimezone = timezone;
+ };
+});