Home > Mobile >  javascript equivalent for oracle date TRUNC function
javascript equivalent for oracle date TRUNC function

Time:10-19

i'm searching for a way to replicate oracle TRUNC date function in javascript

https://www.techonthenet.com/oracle/functions/trunc_date.php

basically its rounding a unix timestamp last interval (round time 11pm to 4hrs will result in 8pm)

my first attempt was:

const trunc = (ts,candleSize) => (Math.floor((ts)/(candleSize)) * candleSize)

but this worked for intervals up to 1hr only.

example: trunc(Date('2021-01-01T13:17:00'), 5*60) === Date('2021-01-01T13:15:00')

but trunc(Date('2021-01-01T13:16:00'), 60*60*4) !== Date('2021-01-01T12:00:00')

so i tried using modulo:

const trunc = (ts,candleSize) => (ts - (ts % candleSize)

and it worked fine for most intervals example: ``

but still i was not able to do things like (Quarter) or (first day of month) or first day of week

CodePudding user response:

I don't know exactly how Oracle's TRUNC works, but here's something that might suit. It will truncate (floor) to any multiple of the specified unit, e.g. start of century is "year*100", start of quarter is "month*3", etc. A missing multiple is 1, so "month" is equivalent to "month*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()}`)
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related