Estoy tratando de convertir una marca de tiempo UTC en una marca de tiempo con formato ISO en hora alemana.
Entrada: 2022-04-30T17:30:00.000000Z
Salida esperada: 2022-04-30T19:30:00
Esta es mi solución de trabajo actual, pero se siente muy... raro... por decir lo menos. Por un lado, me temo que muchos navegadores no podrán convertir correctamente la fecha a la zona horaria alemana.
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); }¿Conoce una solución mejor/mejorada para este problema que sea compatible con la mayoría de los navegadores? Siento que JavaScript debe ofrecer una mejor solución para esta tarea sin tener que depender de bibliotecas externas...
Editar : como alternativa a la función toIsoString , también encontré esto: .toLocaleString("sv-SE") pero supongo que esto tiene un soporte de navegador aún peor.
Si no necesita garantizar el formato de la marca de tiempo resultante, puede usar toLocaleDateString más toLocaleTimeString con una etiqueta de idioma adecuada, por ejemplo
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)}`) );Pero tenga en cuenta que el formato de los métodos toLocale* depende de la implementación y puede variar entre implementaciones, particularmente para idiomas menos comunes y combinaciones de idioma, opciones e idioma predeterminado del host.
Una mejor alternativa es usar Intl.DateTimeFormat con formatToParts , por ejemplo
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)}`) );La opción timeZone no es compatible con IE, pero tal vez eso no importe.