简体   繁体   中英

Convert UTC timestamp to other timezone in ISO format

I am trying to convert a UTC timestamp to an ISO-formatted timestamp in German time.

Input: 2022-04-30T17:30:00.000000Z

Expected Output: 2022-04-30T19:30:00

This is my current, working solution but it feels very... hacky... to say the least. For one, I am afraid that many browsers might not be able to correctly convert the date to the german timezone.

 var inputDateString = "2022-04-30T17:30:00.000000Z"; // Convert to German timezone and formatted as iso date var output = toIsoString(convertTZ(inputDateString, "Europe/Berlin")).split("+")[0]; console.log("inputDateString:", inputDateString) console.log("output:", output) // Ref.: https://stackoverflow.com/a/54127122 function convertTZ(date, tzString) { return new Date((typeof date === "string"? new Date(date): date).toLocaleString("en-US", { timeZone: tzString })); } // Ref.: https://stackoverflow.com/a/17415677 function toIsoString(date) { var tzo = -date.getTimezoneOffset(), dif = tzo >= 0? "+": "-", pad = function (num) { return (num < 10? "0": "") + num; }; return date.getFullYear() + "-" + pad(date.getMonth() + 1) + "-" + pad(date.getDate()) + "T" + pad(date.getHours()) + ":" + pad(date.getMinutes()) + ":" + pad(date.getSeconds()) + dif + pad(Math.floor(Math.abs(tzo) / 60)) + ":" + pad(Math.abs(tzo) % 60); }

Do you know a better/improved solution to this problem that is compatible with most browsers? I feel like JavaScript must offer a better solution for this task without having to rely on external libraries...

Edit : As an alternative to the toIsoString function, I have also found this: .toLocaleString("sv-SE") but I assume that this has even worse browser support.

If you don't need to guarantee the format of the resulting timestamp, you can use toLocaleDateString plus toLocaleTimeString with a suitable language tag, eg

 function getISOLocal(loc, date = new Date()) { return `${date.toLocaleDateString('en-CA', {timeZone: loc})}` + `T${date.toLocaleTimeString('en', {timeZone: loc, hour12:false})}`; } console.log('Current local time in:'); ['Pacific/Midway', 'America/New_York', 'Europe/Berlin', 'Pacific/Kiritimati'].forEach( loc => console.log(`${loc}: ${getISOLocal(loc)}`) );

But be aware that the format of toLocale* methods is implementation dependent and may vary between implementations, particularly for less common languages and combinations of language, options and host default language.

A better alternative is to use Intl.DateTimeFormat with formatToParts , eg

 function getISOLocal(loc, date = new Date()) { let {year, month, day, hour, minute, second} = new Intl.DateTimeFormat('en', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false, timeZone: loc }).formatToParts(date).reduce((acc, part) => { acc[part.type] = part.value; return acc; }, Object.create(null)); return `${year}-${month}-${day}T${hour}:${minute}:${second}` } console.log('Current local time in:'); ['Pacific/Midway', 'America/New_York', 'Europe/Berlin', 'Pacific/Kiritimati'].forEach( loc => console.log(`${loc}: ${getISOLocal(loc)}`) );

The timeZone option isn't supported in IE, but maybe that doesn't matter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM