Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I parse an ISO 8601 formatted duration using moment.js?

I have an ISO 8601 formatted duration, for eg: PT5M or PT120S.

Is there any way I can parse these using moment.js and fetch the number of minutes specified in the duration?

Thank you!

PS: I looked at Parse ISO 8601 durations and Convert ISO 8601 time format into normal time duration

but was keen to know if this was do-able with moment.

like image 790
Qrious Avatar asked Jan 09 '15 00:01

Qrious


People also ask

How do I read the ISO 8601 date format?

ISO 8601 represents date and time by starting with the year, followed by the month, the day, the hour, the minutes, seconds and milliseconds. For example, 2020-07-10 15:00:00.000, represents the 10th of July 2020 at 3 p.m. (in local time as there is no time zone offset specified—more on that below).

How do I specify the duration in an ISO 8601 format?

Briefly, the ISO 8601 notation consists of a P character, followed by years, months, weeks, and days, followed by a T character, followed by hours, minutes, and seconds with a decimal part, each with a single-letter suffix that indicates the unit. Any zero components may be omitted.

How do I convert ISO date to local time?

Use the getTime() method to convert an ISO date to a timestamp, e.g. new Date(isoStr). getTime() . The getTime method returns the number of milliseconds since the Unix Epoch and always uses UTC for time representation.

How do you find time from moment?

The moment(). hour() Method is used to get the hours from the current time or to set the hours.


2 Answers

moment does parse ISO-formatted durations out of the box with the moment.duration method:

moment.duration('P1Y2M3DT4H5M6S')

The regex is gnarly, but supports a number of edge cases and is pretty thoroughly tested.

like image 57
bollwyvl Avatar answered Oct 05 '22 09:10

bollwyvl


It doesn't appear to be one of the supported formats: http://momentjs.com/docs/#/durations/

There aren't any shortage of github repos that solve it with regex (as you saw, based on the links you provided). This solves it without using Date. Is there even a need for moment?

var regex = /P((([0-9]*\.?[0-9]*)Y)?(([0-9]*\.?[0-9]*)M)?(([0-9]*\.?[0-9]*)W)?(([0-9]*\.?[0-9]*)D)?)?(T(([0-9]*\.?[0-9]*)H)?(([0-9]*\.?[0-9]*)M)?(([0-9]*\.?[0-9]*)S)?)?/

minutesFromIsoDuration = function(duration) {
    var matches = duration.match(regex);

    return parseFloat(matches[14]) || 0;
}

If you test it:

minutesFromIsoDuration("PT120S");

0

minutesFromIsoDuration("PT5M");

5

If you want the logical duration in minutes, you might get away with:

return moment.duration({
    years: parseFloat(matches[3]),
    months: parseFloat(matches[5]),
    weeks: parseFloat(matches[7]),
    days: parseFloat(matches[9]),
    hours: parseFloat(matches[12]),
    minutes: parseFloat(matches[14]),
    seconds: parseFloat(matches[16])
});

followed by

result.as("minutes");
like image 27
Mark Dickson Jr. Avatar answered Oct 05 '22 08:10

Mark Dickson Jr.