Parse datetime string as TZ/local
by PhilQ
JavaScript 1.7
function datePartsToYMDHIS(parts) {
parts = parts
.filter(p => p.type!=='literal')
.reduce((o, v) => { o[v.type] = v.value; return o; }, {});
return `${parts.year}-${parts.month}-${parts.day} ${parts.hour}:${parts.minute}:${parts.second}`;
}
function datePartsToISO(parts) {
parts = parts
.filter(p => p.type!=='literal')
.reduce((o, v) => { o[v.type] = v.value; return o; }, {});
return `${parts.year}-${parts.month}-${parts.day}T${parts.hour}:${parts.minute}:${parts.second}.000000Z`;
}
// In: datetime ISO string (in true UTC)
// Out: datetime representation (where UTC is local/tz time)
function dateToTimezone(isoString, timeZone) {
const date = new Date(Date.parse(isoString));
// const date = new Date(isoString);
const dateTimeFormat = new Intl.DateTimeFormat('en-US', {
timeZone: timeZone ?? undefined,
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "numeric",
minute: "numeric",
second: "numeric",
hourCycle: "h23",
});
return new Date( Date.parse(
datePartsToISO( dateTimeFormat.formatToParts( date ) )
) );
}
// In: datetime ISO string (where UTC is local/tz time)
// Out: datetime representation (in true UTC)
function dateFromTimezone(isoString, timeZone) {
const dateUTC = dateToTimezone(isoString, 'UTC');
const dateTZ = dateToTimezone(isoString, timeZone);
const offsetTZ = dateTZ.getTime() - dateUTC.getTime();
const dateCalculated = new Date( dateUTC.getTime() - offsetTZ );
// Note: We need to check (and correct) for DST switching,
// to make sure the calculated date is the correct UTC date
// corresponding to the ISO string local timestamp.
// Check if the calculated date (UTC) gives the correct ISO string in TZ.
const dateTZasUTC = dateToTimezone(dateCalculated.toISOString(), timeZone);
// And correct if necessary (when: isoString !== dateTZasUTC.toISOString()).
return new Date( dateCalculated.getTime() + dateUTC.getTime() -...