Solución:
Nota
La siguiente solución no funcionará para todas las zonas horarias, por lo que si la precisión de la zona horaria es fundamental para su aplicación, es posible que desee probar algo como la respuesta de Beni. Consulte este enlace para obtener más información.
Hoy tuve exactamente la misma pregunta e investigué un poco para ver si alguien había encontrado algo mejor desde que se planteó esta pregunta. Encontré esta solución que se ajusta a mis necesidades y preferencias estilísticas:
import { format, addMinutes } from 'date-fns';
function formatDate(date) {
return format(addMinutes(date, date.getTimezoneOffset()), 'yyyy-MM-dd HH:mm:ss');
}
Explicación
getTimezoneOffset
devuelve el número de minutos necesarios para convertir esa fecha a UTC. En PST (-0800 horas) devolvería 480 mientras que para alguien en CST (+0800 horas) devolvería -480.
Casi estabas ahí. Esto funciona para mi:
import { parseISO } from "date-fns";
import { format, utcToZonedTime } from "date-fns-tz";
const time = "2019-10-25T08:10:00Z";
const parsedTime = parseISO(time);
console.log(parsedTime); // 2019-10-25T08:10:00.000Z
const formatInTimeZone = (date, fmt, tz) =>
format(utcToZonedTime(date, tz),
fmt,
{ timeZone: tz });
const formattedTime = formatInTimeZone(parsedTime, "yyyy-MM-dd kk:mm:ss xxx", "UTC");
console.log(formattedTime); // 2019-10-25 08:10:00 +00:00
Entre bastidores
La fecha-fns[-tz] las bibliotecas se adhieren a las funciones integradas Date
tipo de datos que no lleva información TZ.
Algunas funciones lo tratan como un momento en el tiempo, pero otras como format
trátelo más como una estructura de componentes del calendario: año 2019, …, día 25, hora 08, ….
Ahora el problema es un Date
es internamente sólo un momento en el tiempo. Sus métodos proporcionan un mapeo hacia / desde componentes calendáricos en zona horaria local.
Entonces, para representar una zona horaria diferente, date-fns-tz/utcToZonedTime
produce temporalmente Date
instancias que representan el mal momento en el tiempo – ¡Solo para que sus componentes de calendario en la hora local sean lo que queremos!
Y el date-fns-tz/format
La entrada de zona horaria de la función afecta solamente los caracteres de la plantilla que imprimen la zona horaria (XX..X
, xx..x
, zz..z
, OO..O
).
Consulte https://github.com/marnusw/date-fns-tz/issues/36 para ver un análisis de esta técnica de “cambio” (y de los casos de uso reales que los motivaron) …
Es un poco de bajo nivel y arriesgado, pero la forma específica en que los compuse arriba: formatInTimeZone()
– Creo que es una receta segura.
Sugeriría usar el incorporado Date
util:
const date = new Date("2019-10-25T08:10:00Z");
const isoDate = date.toISOString();
console.log(`${isoDate.substr(0, 10)} ${isoDate.substr(11, 8)}`);
Salidas:
2019-10-25 08:10:00
No es una solución general para ningún formato, pero no se requieren bibliotecas externas.