Sarkar
Sarkar

Reputation: 1879

Convert a Duration(ex. 3h 23m) to datetime in nodejs?

how can I convert time as string like this 2h 25m 15s or 2h 10m into a datetime or just minute like 1h => 60 using NodeJS?

Upvotes: 0

Views: 423

Answers (2)

Rick Stanley
Rick Stanley

Reputation: 850

Another approach is to create a function to split the time, with a regular expression (ReGex) in the specified structure ({number}h {number}m {number}s):

const splitTime = time => time.match(/((?<hours>\d{1,2})(?:h))?\s?((?<minutes>\d{1,2})(?:m))?\s?((?<seconds>\d{1,2})(?:s))?/).groups;

This function accepts and expects an input in the h m s format, each letter preceded by number, then a regex expression is defined for this input, simply put the expression searches for a number (e.g.: (expression 1) (?<hours>\d{1,2})) that is followed by a letter (e.g.: (expression 2) (?:h)), but the letter not elegible to match within the group (expression ?:), we make this expression optional with "?" at the end of the outermost parenthesis of the capturing group, like: (expression 1 expression 2)?, and finally we make the spaces in between optional with \s? (matching exactly one space in between).

Then we can create a function that accepts hours, minutes and seconds, with defaults to 0 (zero), like so:

const timeToSeconds = ({hours = 0, minutes = 0, seconds = 0}) => Number(hours) * 60 * 60 + Number(minutes) * 60 + Number(seconds);

and then use with splitTime function:

const seconds = timeToSeconds(splitTime('1h 25s'));
console.log(seconds); // 3625

Full code with additional functions:

const splitTime = time => time.match(/((?<hours>\d{1,2})(?:h))?\s?((?<minutes>\d{1,2})(?:m))?\s?((?<seconds>\d{1,2})(?:s))?/).groups;

const timeToHours = ({hours = 0, minutes = 0, seconds = 0}) => Number(hours) + Number(minutes) / 60 + Number(seconds) / 60 * 60;

const timeToMinutes = ({hours = 0, minutes = 0, seconds = 0}) => Number(hours) * 60 * 60 + Number(minutes) + Number(seconds) / 60;

const timeToSeconds = ({hours = 0, minutes = 0, seconds = 0}) => Number(hours) * 60 * 60 + Number(minutes) * 60 + Number(seconds);

const time = "1h 15m 0s";
const timeSplit = splitTime(time);

console.log(timeToHours(timeSplit));
console.log(timeToMinutes(timeSplit));
console.log(timeToSeconds(timeSplit));

// Missing hours and seconds
console.log(timeToSeconds(splitTime("15m")));

Upvotes: 0

Heretic Monkey
Heretic Monkey

Reputation: 12114

I couldn't find an exact duplicate for this, but we have many, many similar questions, all similar to Converting a string to a date in JavaScript. Basically, you just need to take a Date and add those values to it. I'd use Date(0) to keep it simple (uses the ECMAScript epoch).

Note I use some recent additions to JavaScript here:

  • ?. The "optional chaining operator" lets me pretend that exec on the regular expression will work. If not, the whole thing returns undefined.
  • ?? The "nullish coalescing operator" handles the case when exec failed to find the unit and returns 0 instead ("nullish" refers to null or undefined).

const durs = [
  '2h 25m 15s',
  '25m 15s',
  '15s',
  '2h 25m',
  '2h',
  '25m'
];

function parseDurationAsDate(duration) {
  const hours = parseInt(/(\d*)h/.exec(duration)?.[0] ?? 0, 10);
  const minutes = parseInt(/(\d*)m/.exec(duration)?.[0] ?? 0, 10);
  const seconds = parseInt(/(\d*)s/.exec(duration)?.[0] ?? 0, 10);
  const date = new Date(0); // date portion is irrelevant
  // especially if we use setUTCHours so that toISOString shows no offset
  date.setUTCHours(hours, minutes, seconds);
  return date;
}
for (let dur of durs) {
  console.log(`Duration:`, dur);
  let dt = parseDurationAsDate(dur);
  console.log('  Date:', dt.toISOString());
  console.log('  Time:', dt.toISOString().slice(11, -1));
}

Upvotes: 1

Related Questions