100 lines
2.7 KiB
JavaScript
100 lines
2.7 KiB
JavaScript
|
"use strict";
|
|||
|
|
|||
|
Object.defineProperty(exports, "__esModule", {
|
|||
|
value: true
|
|||
|
});
|
|||
|
exports.default = tzTokenizeDate;
|
|||
|
|
|||
|
/**
|
|||
|
* Returns the [year, month, day, hour, minute, seconds] tokens of the provided
|
|||
|
* `date` as it will be rendered in the `timeZone`.
|
|||
|
*/
|
|||
|
function tzTokenizeDate(date, timeZone) {
|
|||
|
var dtf = getDateTimeFormat(timeZone);
|
|||
|
return dtf.formatToParts ? partsOffset(dtf, date) : hackyOffset(dtf, date);
|
|||
|
}
|
|||
|
|
|||
|
var typeToPos = {
|
|||
|
year: 0,
|
|||
|
month: 1,
|
|||
|
day: 2,
|
|||
|
hour: 3,
|
|||
|
minute: 4,
|
|||
|
second: 5
|
|||
|
};
|
|||
|
|
|||
|
function partsOffset(dtf, date) {
|
|||
|
try {
|
|||
|
var formatted = dtf.formatToParts(date);
|
|||
|
var filled = [];
|
|||
|
|
|||
|
for (var i = 0; i < formatted.length; i++) {
|
|||
|
var pos = typeToPos[formatted[i].type];
|
|||
|
|
|||
|
if (pos >= 0) {
|
|||
|
filled[pos] = parseInt(formatted[i].value, 10);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return filled;
|
|||
|
} catch (error) {
|
|||
|
if (error instanceof RangeError) {
|
|||
|
return [NaN];
|
|||
|
}
|
|||
|
|
|||
|
throw error;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function hackyOffset(dtf, date) {
|
|||
|
var formatted = dtf.format(date).replace(/\u200E/g, '');
|
|||
|
var parsed = /(\d+)\/(\d+)\/(\d+),? (\d+):(\d+):(\d+)/.exec(formatted); // var [, fMonth, fDay, fYear, fHour, fMinute, fSecond] = parsed
|
|||
|
// return [fYear, fMonth, fDay, fHour, fMinute, fSecond]
|
|||
|
|
|||
|
return [parsed[3], parsed[1], parsed[2], parsed[4], parsed[5], parsed[6]];
|
|||
|
} // Get a cached Intl.DateTimeFormat instance for the IANA `timeZone`. This can be used
|
|||
|
// to get deterministic local date/time output according to the `en-US` locale which
|
|||
|
// can be used to extract local time parts as necessary.
|
|||
|
|
|||
|
|
|||
|
var dtfCache = {};
|
|||
|
|
|||
|
function getDateTimeFormat(timeZone) {
|
|||
|
if (!dtfCache[timeZone]) {
|
|||
|
// New browsers use `hourCycle`, IE and Chrome <73 does not support it and uses `hour12`
|
|||
|
var testDateFormatted = new Intl.DateTimeFormat('en-US', {
|
|||
|
hour12: false,
|
|||
|
timeZone: 'America/New_York',
|
|||
|
year: 'numeric',
|
|||
|
month: 'numeric',
|
|||
|
day: '2-digit',
|
|||
|
hour: '2-digit',
|
|||
|
minute: '2-digit',
|
|||
|
second: '2-digit'
|
|||
|
}).format(new Date('2014-06-25T04:00:00.123Z'));
|
|||
|
var hourCycleSupported = testDateFormatted === '06/25/2014, 00:00:00' || testDateFormatted === '06/25/2014 00:00:00';
|
|||
|
dtfCache[timeZone] = hourCycleSupported ? new Intl.DateTimeFormat('en-US', {
|
|||
|
hour12: false,
|
|||
|
timeZone: timeZone,
|
|||
|
year: 'numeric',
|
|||
|
month: 'numeric',
|
|||
|
day: '2-digit',
|
|||
|
hour: '2-digit',
|
|||
|
minute: '2-digit',
|
|||
|
second: '2-digit'
|
|||
|
}) : new Intl.DateTimeFormat('en-US', {
|
|||
|
hourCycle: 'h23',
|
|||
|
timeZone: timeZone,
|
|||
|
year: 'numeric',
|
|||
|
month: 'numeric',
|
|||
|
day: '2-digit',
|
|||
|
hour: '2-digit',
|
|||
|
minute: '2-digit',
|
|||
|
second: '2-digit'
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
return dtfCache[timeZone];
|
|||
|
}
|
|||
|
|
|||
|
module.exports = exports.default;
|