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.
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