Home > Enterprise >  How to format JavaScript Date object to not let hours overflow?
How to format JavaScript Date object to not let hours overflow?

Time:06-30

Let us consider following example

const date = new Date(0);
date.setSeconds(60*60*24-1);
console.log(date.toISOString().substr(11, 8));

outputs

23:59:59

I am searching for elegant way to have

const date = new Date(0);
date.setSeconds(60*60*24 1);
console.log(date.toISOString().substr(11, 8));

output

24:00:01

instead of

00:00:01

by elegant I mean without implementing my own Date object... Maybe it would be possible to set a custom length of the day? Increase from 24h to 99h?

CodePudding user response:

You can set the hour cycle in the hour cycle option (hc) and the language parameter available in the Intl.DateTimeFormat constructor and toLocaleTimeString, e.g.

console.log(
  new Date(2020,7,1,0,5).toLocaleTimeString('en-CA-u-hc-h24')
);

Whether the hour cycle setting "works" or not seems to depend on the language chosen and how it's set, so maybe not that reliable. Test thoroughly in different implementations.

CodePudding user response:

Many thanks to @RobG who understood my question. The hour cycle is what I needed, unfortunately according to the docs it is restricted to values h11, h12, h23, h24 and I would need h99 which is not available.

Eventually I had to make my own ugly solution as it appears such a use case was not predicted in the standard, so here it is

function unfortunatelyWeHadToWriteIt(nbsec) {
  // compute numerical values
  const nbhours = Math.floor(nbsec/(60*60));
  const nbminutes = Math.floor((nbsec - nbhours*60*60)/60)
  const nbseconds = Math.floor(nbsec - nbhours*60*60 - nbminutes*60);
  // convert them to padded strings
  const hours = String(nbhours).padStart(2, '0');
  const minutes = String(nbminutes).padStart(2, '0');
  const seconds = String(nbseconds).padStart(2, '0');
  // format
  return `${hours}:${minutes}:${seconds}`;
}

so let's compare it to the Date formatting

// 27 hours, 13 minutes and 6 seconds
const nbsec = 60*60*27 13*60 6;

what Date will give us

const date = new Date(0);
date.setSeconds(nbsec);
console.log(date.toISOString().substr(11, 8));

outputs 03:13:06, it overflows at value of 24 hours. Now let's apply the unfortunatelyWeHadToWriteIt function

console.log(unfortunatelyWeHadToWriteIt(nbsec))

outputs 27:13:06 which does not overflow.

Just to give you guys some context, I am playing games and displaying the playtime. It is more convenient to show number of hours than number of days of gameplay...

  • Related