I came across a bug in DateTime::Format::Pg->parse_duration whereby it does not parse the following intervals

@ x hours
@ y minutes
@ z seconds

This was frustrating because the format->duration does output these values.

Attached is a patch which fixes this behaviour.

Cheers,
Brett Gardner



Index: t/parse_interval.t
===================================================================
--- t/parse_interval.t	(revision 3990)
+++ t/parse_interval.t	(working copy)
@@ -94,6 +94,13 @@
             hours => -2,
             minutes => -3,
         )],
+
+        ['@ 40 minutes' => DateTime::Duration->new(minutes=>40)],
+        ['@ 180 minutes' => DateTime::Duration->new(hours=>3)],
+        ['@ 40 seconds' => DateTime::Duration->new(seconds=>40)],
+        ['@ 180 seconds' => DateTime::Duration->new(minutes=>3)],
+        ['@ 3 hours' => DateTime::Duration->new(minutes=>180)],
+        ['@ 25 hours' => DateTime::Duration->new(days=>1,hours=>1)],
     );
 
     plan tests => @negative_data + @positive_data + 1;
Index: lib/DateTime/Format/Pg.pm
===================================================================
--- lib/DateTime/Format/Pg.pm	(revision 3990)
+++ lib/DateTime/Format/Pg.pm	(working copy)
@@ -552,12 +552,15 @@
 
 sub parse_duration {
     my ($self, $string) = @_;
-    my ($year, $mon, $day, $sgn, $hour, $min, $sec, $frc, $ago) = $string =~ m{
+    my ($year, $mon, $day, $hours, $minutes, $seconds, $sgn, $hour, $min, $sec, $frc, $ago) = $string =~ m{
         \A                                     # Start of string.
         (?:[EMAIL PROTECTED])?                             # Optional leading @.
         (?:([-+]?\d+)\s+years?\s*)?            # years
         (?:([-+]?\d+)\s+mons?\s*)?             # months
         (?:([-+]?\d+)\s+days?\s*)?             # days
+        (?:([-+]?\d+)\s+hours?\s*)?            # hours
+        (?:([-+]?\d+)\s+minutes?\s*)?          # minutes
+        (?:([-+]?\d+)\s+seconds?\s*)?          # seconds
         (?:                                    # Start h/m/s
           # hours
           (?:([-+])?([0-9]\d|[1-9]\d{2,}(?=:)|\d+(?=\s+hour))(?:\s+hours?)?\s*)?
@@ -570,6 +573,10 @@
         \z                                     # End of string
     }xms or croak "Invalid interval string $string";
 
+    $hour ||= $hours;
+    $min ||= $minutes;
+    $sec ||= $seconds;
+
     # NB: We can't just pass our values to new() because it treats all
     # arguments as negative if we have a single negative component.
     # PostgreSQL might return mixed signs, e.g. '1 mon -1day'.

Reply via email to