Reputation: 1879
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
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
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