Tengo una función en Java para convertir una fecha de Época a ISO 8601, pero me encontré con la necesidad de hacerlo en Javascript. Lo tengo funcionando un poco en JS, pero debe localizarse en la zona horaria.
Versión Java:
public static String epochToIso8601(long time, String Zone) {
String format = "yyyy-MM-dd'T'HH:mm:ssX";
TimeZone timeZone = TimeZone.getTimeZone(Zone);
SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.getDefault());
sdf.setTimeZone(timeZone);
return sdf.format(new Date(time));
}
Parámetro1: -157737600000
Param2: PST
Salida: 1965-01-01T00:00:00-08
Mi intento en Javascript:
function epcov(epoch, timezone)
{
var someValueNum = Number(epoch);
var s = new Date(someValueNum);
return s.toISOString();
}
Esencialmente, quiero lo mismo que sale de Java, pero está generando: 1965-01-01T08: 00: 00.000Z
Por cierto, ya estoy dividiendo la fecha y la hora de algo que se parece a esto, por lo que si es mejor pasar lo siguiente como una cadena y dejar que Javascript la analice, sería increíble:
/Date(-157737600000-0800)/
Podemos convertir la cadena /Date(-157737600000-0800)/ a una hora Unix (en ms) y un desplazamiento UTC en HHMM usando String.match() .
El desplazamiento UTC de HHMM se puede convertir a un desplazamiento UTC en milisegundos multiplicando el valor HH por 3600000 y el valor MM por 60000.
Luego creamos un nuevo objeto Fecha usando los valores de tiempo y compensación de Unix, ya que conocemos la compensación exacta en ese punto en el tiempo.
Luego formateamos usando Date.toISOString() y reemplazamos el valor de zona horaria de compensación UTC 'Z' con la cadena de compensación UTC real (por ejemplo, '-08:00').
function parseAndFormatDate(date) {
const [,millis, offset] = date.match(/([+\-]+\d+)([+\-]+\d+)/);
const offsetMillis = (offset.slice(0, 1) + '1') * (offset.slice(1, 3) * 3600000 + offset.slice(-2) * 60000);
const formattedOffset = offset.slice(0, 3) + ':' + offset.slice(-2);
return new Date(+millis + offsetMillis).toISOString().replace('Z', formattedOffset);
}
console.log(parseAndFormatDate('/Date(-157737600000-0800)/'));
console.log(parseAndFormatDate('/Date(+1664271413000+0100)/'));
.as-console-wrapper { max-height: 100% !important; }
Espero que esto te ayude de alguna manera.
JS no tiene un buen soporte (¡¿alguno?!) para exportar una cadena ISO 8601 en una zona horaria específica. Así que tienes que construir la cadena tú mismo, manualmente.
El uso de la configuración regional sueca es obtener una base similar a la ISO 8601 desde la cual extraer los elementos de la fecha y la hora. Desafortunadamente, no hay una configuración regional de formato ISO 8601.
Tenga en cuenta que lo siguiente solo funcionará de manera confiable con los nombres de las zonas horarias de la IANA porque las abreviaturas de las zonas horarias (PST, CST, BST) pueden ser ambiguas . Por ejemplo: V8 aceptará 'PST' pero SpiderMonkey no.
// Get wall clock date at the specified tz in IS0 8601
const getISO8601Date = (d, timeZone) =>
d.toLocaleString('sv-SE', { timeZone, dateStyle: 'short'})
// Get wall clock time at the specified tz in IS0 8601
const getISO8601Time = (d, timeZone) =>
d.toLocaleString('sv-SE', { timeZone, timeStyle: 'medium'})
// Get time zone offset in specified tz in IS0 8601
const getISO8601TimeZoneOffset = (d, timeZone) => {
const s = d.toLocaleString('sv-SE', { timeZone, timeZoneName: 'longOffset' })
const result = /GMT(?<offset>[+−]\d\d:\d\d)/.exec(s) // Use regexp to pull out offset
return result ? result.groups.offset : 'Z'
}
// Put together an ISO 8601 string representing the wall clock at the specified date, in the specified timezone
const getISO8601Dtg = (instant, timeZone) => {
const d = new Date(instant)
return `${getISO8601Date(d, timeZone)}T${getISO8601Time(d, timeZone)}${getISO8601TimeZoneOffset(d, timeZone)}`
}
// Only reliably accepts IANA timezone names eg. 'America/Los_Angeles'
console.log(getISO8601Dtg(-157737600000, 'America/Los_Angeles')) // 1965-01-01T00:00:00−08:00