123 lines
3.5 KiB
JavaScript
123 lines
3.5 KiB
JavaScript
var typeToPos = {
|
|
year: 0,
|
|
month: 1,
|
|
day: 2,
|
|
hour: 3,
|
|
minute: 4,
|
|
second: 5
|
|
};
|
|
var ms = 'ms';
|
|
export default (function (o, c, d) {
|
|
var defaultTimezone;
|
|
var localUtcOffset = d().utcOffset();
|
|
|
|
var tzOffset = function tzOffset(timestamp, timezone) {
|
|
var date = new Date(timestamp);
|
|
var 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'
|
|
});
|
|
var formatResult = dtf.formatToParts(date);
|
|
var filled = [];
|
|
|
|
for (var i = 0; i < formatResult.length; i += 1) {
|
|
var _formatResult$i = formatResult[i],
|
|
type = _formatResult$i.type,
|
|
value = _formatResult$i.value;
|
|
var pos = typeToPos[type];
|
|
|
|
if (pos >= 0) {
|
|
filled[pos] = parseInt(value, 10);
|
|
}
|
|
} // Workaround for the same behavior in different node version
|
|
// https://github.com/nodejs/node/issues/33027
|
|
|
|
|
|
var hour = filled[3];
|
|
var fixedHour = hour === 24 ? 0 : hour;
|
|
var utcString = filled[0] + "-" + filled[1] + "-" + filled[2] + " " + fixedHour + ":" + filled[4] + ":" + filled[5] + ":000";
|
|
var utcTs = d.utc(utcString).valueOf();
|
|
var asTS = +date;
|
|
var 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
|
|
|
|
|
|
var fixOffset = function fixOffset(localTS, o0, tz) {
|
|
// Our UTC time is just a guess because our offset is just a guess
|
|
var utcGuess = localTS - o0 * 60 * 1000; // Test whether the zone matches the offset for this ts
|
|
|
|
var 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
|
|
|
|
var 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)];
|
|
};
|
|
|
|
var proto = c.prototype;
|
|
|
|
proto.tz = function (timezone) {
|
|
if (timezone === void 0) {
|
|
timezone = defaultTimezone;
|
|
}
|
|
|
|
var target = this.toDate().toLocaleString('en-US', {
|
|
timeZone: timezone
|
|
});
|
|
var diff = Math.round((this.toDate() - new Date(target)) / 1000 / 60);
|
|
return d(target).utcOffset(localUtcOffset - diff, true).$set(ms, this.$ms);
|
|
};
|
|
|
|
d.tz = function (input, timezone) {
|
|
if (timezone === void 0) {
|
|
timezone = defaultTimezone;
|
|
}
|
|
|
|
var previousOffset = tzOffset(+d(), timezone);
|
|
var localTs;
|
|
|
|
if (typeof input !== 'string') {
|
|
// timestamp number || js Date || Day.js
|
|
localTs = d(input) + previousOffset * 60 * 1000;
|
|
}
|
|
|
|
localTs = localTs || d.utc(input).valueOf();
|
|
|
|
var _fixOffset = fixOffset(localTs, previousOffset, timezone),
|
|
targetTs = _fixOffset[0],
|
|
targetOffset = _fixOffset[1];
|
|
|
|
var ins = d(targetTs).utcOffset(targetOffset);
|
|
return ins;
|
|
};
|
|
|
|
d.tz.guess = function () {
|
|
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
};
|
|
|
|
d.tz.setDefault = function (timezone) {
|
|
defaultTimezone = timezone;
|
|
};
|
|
}); |