Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting ISO8601 duration (P3Y6M...) to seconds in perl

Tags:

iso8601

perl

I'm trying to convert an ISO 8601 time duration format, P3Y6M4DT12H30M5S, to seconds in perl. Is there a library that does this? I've tried searching, but I've only found a js library. Looking through DateTime and Time::Moment didn't provide a solution either.

like image 916
Orjanp Avatar asked Oct 22 '25 04:10

Orjanp


1 Answers

There is DateTime::Format::Duration::ISO8601, which can convert the ISO 8601 duration string into a DateTime::Duration object. You can then convert that to seconds.

use DateTime::Duration;
use DateTime::Format::Duration::ISO8601;

my $format = DateTime::Format::Duration::ISO8601->new;
my $d = $format->parse_duration('P3Y6M4DT12H30M5S');

However, the DateTime::Duration format cannot be used to convert a year to seconds, as explained in the docs here.

The last example demonstrates that there will not be any conversion between units which don't have a fixed conversion rate. The only conversions possible are:

years <=> months
weeks <=> days
hours <=> minutes
seconds <=> nanoseconds

For the explanation of why this is the case, please see the How DateTime Math Works section of the DateTime.pm documentation

You can use DateTime::Format::Duration with the %s pattern to circumvent that. A complete implementation might look like this.

use DateTime::Duration;
use DateTime::Format::Duration::ISO8601;
use DateTime::Format::Duration;

my $format = DateTime::Format::Duration::ISO8601->new;
my $d      = $format->parse_duration('P3Y6M4DT12H30M5S');

my $output_format = DateTime::Format::Duration->new( pattern => '%s' );
print $output_format->format_duration($d);

Or, in short if you only need it once.

use DateTime::Duration;
use DateTime::Format::Duration::ISO8601;
use DateTime::Format::Duration;

print DateTime::Format::Duration->new( pattern => '%s' )
    ->format_duration(
    DateTime::Format::Duration::ISO8601->new->parse_duration('P3Y6M4DT12H30M5S') );

Both of these will print

109254605
like image 144
simbabque Avatar answered Oct 24 '25 04:10

simbabque