views:

52

answers:

3

I'm writing a perl script that takes a "duration" option, and I'd like to be able to specify this duration in a fairly flexible manner, as opposed to only taking a single unit (e.g. number of seconds). The UNIX at command implements this kind of behavior, by allowing specifications such as "now + 3 hours + 2 days". For my program, the "now" part is implied, so I just want to parse the stuff after the plus sign. (Note: the at command also parses exact date specifications, but I only want to parse durations.)

Is there a perl module for parsing duration specifications like this? I don't need the exact syntax accepted by at, just any reasonable syntax for specifying time durations.


Edit: Basically, I want something like DateTime::Format::Flexible for durations instead of dates.

+1  A: 

Take a look at DateTime::Duration and DateTime::Format::Duration:

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

my $formatter = DateTime::Format::Duration->new(
        pattern => '%e days, %H hours'
);

my $dur = $formatter->parse_duration('2 days, 5 hours');
my $dt = DateTime->now->add_duration($dur);
Ether
`DateTime::Format::Duration` does not seem to accept flexible time specifications. You can make up your own time specification, but then it will only parse *exactly* that spec. Case in point, your example wouldn't work unless you did `$formatter->parse_duration('0 years, 0 months, 2 days, 5 hours, 0 minutes, 0 seconds')`.
Ryan Thompson
A: 

Time::ParseDate has pretty flexible syntax for relative times. Note that it always returns an absolute time, so you can't tell the difference between "now + 3 hours + 2 days" and "3 hours + 2 days" (both of those are valid inputs to parsedate, and will return the same value). You could subtract time if you want to get a duration instead.

Also, it doesn't return DateTime objects, just a UNIX epoch time. I don't know if that's a problem for your application.

cjm
A: 

I ended up going with Time::Duration::Parse.

Ryan Thompson