Javascript date string conversion

I am working with an API that delivers a date like this:

P20DT9H1M14S

Standing for a period of 20 days, and time of 9 hours, 1 minute, and 14 seconds.

I am trying to figure out how to convert the P20DT9H1M14S to this:

20 days, 9 hours, 1 minute, and 14 seconds.

Any ideas?

A regular expression would work.


var periodCode = 'P20DT9H1M14S';
var match = /P(\\d+)DT(\\d+)H(\\d+)M(\\d+)S/.exec(periodCode);
var period = match[1] + ' days, ' + match[2] + ' hours, ' + match[3] + ' minutes, ' + match[4] + ' seconds.'
// period is 20 days, 9 hours, 1 minute, and 14 seconds.

What if the date format may not always stay the same? Like if there is 0 days, it returns:

PT9H15M47S

Or if there is 0 hours it returns:

P4DT31M17S

Can the regular expression work with a string that may be variable like this, or would it be best to split the string into Days, Hours, Minutes, and Seconds and then manipulate the string based on if the variable isNaN or not?

I’m glad that you liked it. Here’s an even simpler regular expression than my previous one.


alert(parseDate('P20DT9H1M14S'));

function parseDate(sourceString) {
    return sourceString.replace(
        /P(\\d+)DT(\\d+)H(\\d+)M(\\d+)S/,
        '$1 days, $2 hours, $3 minutes, $4 seconds.'
    );
}

Nice one, PMW! I understand regular expressions perfectly when presented with a straight-forward example like that. Unfortunately most RegEx tutorials around the web try teaching you to run before you can crawl which results in misunderstandings and confusion.

Here’s how we’d do this if regular expressions didn’t exist. Note this version doesn’t pluralize the unit if the value is 1 :wink:

alert(parseDate('P20DT9H1M14S'));

function parseDate(sourceString){
 d = parseInt(sourceString.split('P')[1]);
 h = parseInt(sourceString.split('DT')[1]);
 m = parseInt(sourceString.split('H')[1]);
 s = parseInt(sourceString.split('M')[1]);
    
 formatted_d = d + ' day' + ((d != 1) ? 's, ' : ', ');
 formatted_h = h + ' hour' + ((h != 1) ? 's, ' : ', ');
 formatted_m = m + ' minute' + ((m != 1) ? 's, ' : ', ');
 formatted_s = s + ' second' + ((s != 1) ? 's' : '');
    
 formattedDate = formatted_d+formatted_h+formatted_m+formatted_s;
 return formattedDate;
}

You can use \d* which gets 0 or more digits, and use D? to say that the D is optional.


alert(parseDate('P20DT9H1M14S'));
 
function parseDate(sourceString) {
    var match = /P(\\d*)D?T(\\d*)H?(\\d*)M?(\\d*)S?/.exec(sourceString);
    return Number(match[1]) + ' days, ' +
        Number(match[2]) + ' hours, ' +
        Number(match[3]) + ' minutes, ' +
        Number(match[4]) + ' seconds.';
}

It wouldn’t be much more difficult then to customise for singular terms. For example:

… + ’ hour’ + (match[2] <> 1 ? ‘s’) + …

If you want some parts such as 0 days to not be shown, you would need to build the final string using separate if conditions as a part of the function instead.