estoy buscando una forma de replicar la función de fecha de Oracle TRUNC en javascript
https://www.techonthenet.com/oracle/functions/trunc_date.php
Básicamente, se trata de redondear un último intervalo de marca de tiempo de Unix (el tiempo de redondeo de 11 p. m. a 4 horas dará como resultado 8 p. m.)
mi primer intento fue:
const trunc = (ts,candleSize) => (Math.floor((ts)/(candleSize)) * candleSize)
pero esto funcionó solo para intervalos de hasta 1 hora.
ejemplo: trunc(Date('2021-01-01T13:17:00'), 5*60) === Date('2021-01-01T13:15:00')
pero trunc(Date('2021-01-01T13:16:00'), 60*60*4) !== Date('2021-01-01T12:00:00')
así que intenté usar módulo:
const trunc = (ts,candleSize) => (ts - (ts % candleSize)
y funcionó bien para la mayoría de los intervalos ejemplo: ``
pero aún no pude hacer cosas como (Trimestre) o (primer día del mes) o primer día de la semana
No sé exactamente cómo funciona el TRUNC de Oracle, pero aquí hay algo que podría ser adecuado. Se truncará (piso) a cualquier múltiplo de la unidad especificada, por ejemplo, el comienzo del siglo es "año*100", el comienzo del trimestre es "mes*3", etc. Un múltiplo faltante es 1, por lo que "mes" es equivalente a "mes*1".
/* Truncate date to previous full unit, does not * modify passed date. * Start of week is Monday. * * @param {Date} date - date to truncate * @param {string} unit - one of: year, month, week, * day, hour, minute, second * optional subunit separated by * * hour*12 = trunc to nearest whole multiple of 12 hours * minute*10 = trunc to nearest whole multiple of 10 minutes * * @returns {Date} truncated Date */ function trunc(date = new Date(), unit = 'day') { let d = new Date(+date); // Parse unit & subunit unit = unit.toLowerCase(); let [u, uSub] = unit.split('*'); // Deal with invalid or missing sub unit if (!Number.isInteger(+uSub)) uSub = 1; // Truncating functions let f = { year: d => [d.getFullYear() - d.getFullYear() % uSub, 0], month: d => [d.getFullYear(), d.getMonth() - d.getMonth() % uSub], // Start of week is Monday week: d => [d.getFullYear(), d.getMonth(), d.getDate() - d.getDay() + 1], day: d => [d.setHours(0,0,0,0)], hour: d => [d.setHours(d.getHours() - d.getHours() % uSub, 0,0,0)], minute: d => [d.setMinutes(d.getMinutes() - d.getMinutes() % uSub, 0,0)], second: d => [d.setSeconds(d.getSeconds() - d.getSeconds() % uSub)], millisecond: d => [d.setMilliseconds(d.getMilliseconds() - d.getMilliseconds() % uSub)] }; // Validate unit & call appropriate function if (f.hasOwnProperty(u)) { return new Date(...f[u](d)); } // If invalid unit, return undefined } // Examples let d = new Date(2019, 11, 15, 23, 59, 41, 55); console.log('Test date => ' + d.toString()); 'year*100 year*10 year month*3 month week day hour*12 hour*6 hour*4 hour*3 hour*2 hour minute*30 minute*20 minute*15 minute*10 minute*5 minute second*30 second'.split(' ') .forEach( unit => console.log(`${unit} => ${trunc(d, unit).toString()}`) ); // Default (start of today) console.log(`Default => ${trunc().toString()}`)