Me dan una marca de tiempo de Unix como esta: 1655402413 y necesito encontrar la medianoche del lunes (en formato UTC/GMT) de la misma semana, independientemente de qué día sea o qué zona horaria. Luego necesito representar ese lunes como una marca de tiempo de Unix y devolverlo. La función que tengo es la siguiente:
function findMonday(unixTimeStamp) { let startDate = new Date(unixTimeStamp); let startDay = startDate.getDay(); let diff = startDate.getDate() - startDay + (startDay === 0 ? -6 : 1); let monday = new Date(startDate.setDate(diff)); monday.setHours(0, 0, 0, 0); monday = new Date(monday).valueOf(); return monday; }Esa función casi funciona, pero hay dos problemas, ambos relacionados con el hecho de que la Fecha parece funcionar siempre con la zona horaria actual del usuario:
startDate evalúa como el domingo anterior al lunes), lo cual no es bueno .monday que se devuelve está en la hora local, no en la hora UTC/GMT.Esto me está volviendo absolutamente loco. Trabajar con fechas en JavaScript es una pesadilla, y agradecería cualquier dirección que me puedan dar.
Multiplique la marca de tiempo de Unix por 1000 y use los métodos UTC como getUTCDate en lugar de getDate , setUTCHours en lugar de setHours , etc.
Por supuesto, para regresar como tiempo Unix, solo divida por 1000.
p.ej.
function findMonday(unixTimeStamp) { let startDate = new Date(unixTimeStamp * 1000); let startDay = startDate.getUTCDay(); let diff = startDate.getUTCDate() - startDay + (startDay === 0 ? -6 : 1); let monday = new Date(startDate.setUTCDate(diff)); monday.setUTCHours(0, 0, 0, 0); monday = new Date(monday).valueOf(); return monday; } const monday = findMonday(1655402413); const unixMonday = Math.trunc(monday / 1000); console.log('The Date: ' + new Date(monday).toISOString()); console.log('Unix time: ' + unixMonday);En cuanto a la respuesta de Keith, pero un poco más concisa. Devuelve segundos, no milisegundos. ;-)
// Given UNIX timestamp, return similar timestamp for // previous UTC Monday at 00:00:00 let getLastUTCMonday = ts => { let d = new Date(ts * 1e3); d.setUTCDate(d.getUTCDate() - (d.getUTCDay() || 7) + 1); return d.setUTCHours(0,0,0,0) / 1e3 | 0; }; let ts = 1655402413; let tsPriorMonday = getLastUTCMonday(ts) console.log( `Start date : ${new Date(ts*1e3).toUTCString()}\n` + `Prior Monday: ${new Date(tsPriorMonday * 1e3).toUTCString()}` );En ECMA-262, las compensaciones de la época (en milisegundos) se denominan "valores de tiempo". Una marca de tiempo es cualquier cosa que represente una hora o una fecha, por lo que un valor de tiempo es una marca de tiempo. ;-)
Dado que los días UTC de ECMAScript siempre duran exactamente 8,64e7 milisegundos, puede calcular el lunes UTC anterior a partir de hoy mediante una aritmética simple.
La época de ECMAScript fue el jueves 1 de enero de 1970 a las 00:00:00, por lo que puede:
El algoritmo anterior solo funciona para fechas posteriores a la época. Las fechas anteriores tienen valores de tiempo negativos, así que agregue 3 días antes de obtener el resto, luego reste el resto + 7 días (es decir, fecha - resto - 7 días).
Lo siguiente solo hace el cálculo posterior a la época:
let getPreviousUTCMonday = date => { let weekRem = (date - 34.56e7) % 60.48e7; return date - weekRem; } let d = new Date(); for (let i=0; i<12; i++) { console.log(`${d.toUTCString()}\n` + `${new Date(getPreviousUTCMonday(d)).toUTCString()}`); d.setDate(d.getDate() + 1); }