Necesito convertir la cadena: '20211114025320+0000' a objeto JS Date (2021-11-14T02:53:20.000Z).
Tengo este formato para información ('YYYYMMDDHHmmssZ'), ¿tal vez necesito usar una función personalizada para esto?
Una función para analizar la cadena y pasar las partes directamente al constructor de Fecha puede ser más eficiente que analizar la cadena para generar otra cadena que luego es analizada por el analizador incorporado.
Este método también evita el analizador integrado, que generalmente se considera una buena idea.
// Parse YYYYMMDDHHmmss±HHmm or YYYYMMDDHHmmssZ function parseTS(ts) { // Get parts let [C,Y,M,D,H,m,s,sign,oH,oM] = ts.match(/\d\d|\D/g); // Deal with offset: ±HHmm or Z if (sign == 'Z') { sign = oH = oM = 0; } let oSign = sign == '+' ? -1 : +1; // Create date from parts, adjust H, m for offset return new Date(Date.UTC(C+Y, M-1, D, +H + oH*oSign, +m + oM*oSign, s)); } ['20211114082320+0530', '20211114025320+0000', '20211114025320Z', '20211113225320-0400' ].forEach(ts => console.log(ts + '\n' + parseTS(ts).toISOString()));Parece que lo que tiene es una cadena ISO 8601 con todos los separadores eliminados.
Por lo tanto, una forma sencilla sería volver a agregar estos separadores usando un reemplazo de expresiones regulares y luego analizarlo usando el analizador incorporado:
function parseCustomDate (s) { const isoString = s.replace(/^(....)(..)(..)(..)(..)(.*)$/, '$1-$2-$3T$4:$5:$6') return new Date(isoString) } (Tenga en cuenta que aquí el último grupo de captura con .* captura tanto los segundos como el especificador de zona horaria a la vez, porque de todos modos no necesitan un separador entre ellos. Para que quede más claro, también puede usar (..)(.*) y $6$7 en lugar de solo (.*) y $6 como hice yo).
Otra forma que es más rápida computacionalmente pero también más compleja para leer, comprender y detectar errores (al menos en mi opinión) sería tomar las partes individuales de la cadena y pasarlas al constructor Date.UTC en lugar de pasar por el ISO ruta de cadena:
function parseCustomDate (s) { const year = Number(s.slice(0, 4)) const month = Number(s.slice(4, 6)) const day = Number(s.slice(6, 8)) const hour = Number(s.slice(8, 10)) const minute = Number(s.slice(10, 12)) const second = Number(s.slice(12, 14)) const tzSign = s.slice(14, 15) const tzHour = Number(tzSign + s.slice(15, 17)) || 0 const tzMinute = Number(tzSign + s.slice(17, 19)) || 0 return new Date(Date.UTC( year, month - 1, day, hour - tzHour, minute - tzMinute, second )) } Explicación para el manejo de la zona horaria aquí: JavaScript acepta fechas "no válidas" que tienen partes individuales fuera del rango normal al cambiarlas, por ejemplo, 11:70:00 se convertiría en 12:10:00. Es por eso que podemos simplemente restar las partes de la zona horaria (con cada parte capturando también el signo + / - ), y ni siquiera tenemos que preocuparnos por multiplicar los minutos por 60 porque también podemos manejarlos en la parte de los minutos.
Agregué el || 0 , de modo que una cadena con una Z como zona horaria que, de lo contrario, haría tzHour y tzMinute NaN también se manejaría como una compensación de zona horaria cero.