Bug 12669: Centralize the timezone handle into Koha::DateUtils
authorJonathan Druart <jonathan.druart@biblibre.com>
Tue, 16 Sep 2014 11:15:57 +0000 (13:15 +0200)
committerMason James <mtj@kohaaloha.com>
Fri, 28 Aug 2015 05:13:31 +0000 (17:13 +1200)
This patch adds unit tests for the previous changes and centralize the
timezone handle into the Koha::DateUtils module.
Like that the behavior will affect all date manipulations using this
module (should be all dates in Koha).

Signed-off-by: Chris Cormack <chris@bigballofwax.co.nz>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Mason James <mtj@kohaaloha.com>

Koha/DateUtils.pm
Koha/Template/Plugin/KohaDates.pm
t/DateUtils.t
t/db_dependent/Koha_template_plugin_KohaDates.t

index 0d4b0dd..fe5e2bc 100644 (file)
@@ -53,9 +53,14 @@ to the system preferences. If the date string is empty DateTime->now is returned
 
 sub dt_from_string {
     my ( $date_string, $date_format, $tz ) = @_;
-    if ( !$tz ) {
-        $tz = C4::Context->tz;
-    }
+
+
+    # FIXME: see bug 13242 => no TZ for dates 'infinite'
+    return DateTime::Format::DateParse->parse_datetime($date_string)
+        if $date_string and $date_string =~ /^9999-/;
+
+    my $dt;
+    $tz ||= C4::Context->tz;
     if ( !$date_format ) {
         $date_format = C4::Context->preference('dateformat');
     }
@@ -84,10 +89,21 @@ s/(\d{4})(\d{2})(\d{2})\s+(\d{2})(\d{2})(\d{2})/$1-$2-$3T$4:$5:$6/;
                 $date_string =~ s/00T/01T/;
             }
         }
-        return DateTime::Format::DateParse->parse_datetime( $date_string,
-            $tz->name() );
+
+        $dt = eval {
+            DateTime::Format::DateParse->parse_datetime( $date_string,
+                $tz->name() );
+        };
+        if ($@) {
+            $tz = DateTime::TimeZone->new( name => 'floating' );
+            $dt = DateTime::Format::DateParse->parse_datetime( $date_string,
+                $tz->name() );
+        }
+    } else {
+        $dt = DateTime->now( time_zone => $tz );
     }
-    return DateTime->now( time_zone => $tz );
+
+    return $dt;
 
 }
 
index b4c1d8d..711255a 100644 (file)
@@ -30,8 +30,7 @@ sub filter {
     return "" unless $text;
     $config->{with_hours} //= 0;
 
-    my $tz = DateTime::TimeZone->new(name => 'floating') unless $config->{with_hours};
-    my $dt = dt_from_string( $text, 'iso', $tz );
+    my $dt = dt_from_string( $text, 'iso' );
 
     return $config->{as_due_date} ?
         output_pref({ dt => $dt, as_due_date => 1 }) :
index 9afddc1..8103ae0 100755 (executable)
@@ -5,7 +5,7 @@ use DateTime;
 use DateTime::TimeZone;
 
 use C4::Context;
-use Test::More tests => 34;
+use Test::More tests => 36;
 use Test::MockModule;
 
 BEGIN { use_ok('Koha::DateUtils'); }
@@ -145,3 +145,26 @@ $date_string = output_pref({ dt => $dt, dateformat => 'metric', timeformat => '2
 cmp_ok $date_string, 'eq', '11/12/2013 18:35', 'as_due_date with hours and timeformat 24hr (non-midnight time)';
 $date_string = output_pref({ dt => $dt, dateformat => 'us', timeformat => '12hr', as_due_date => 1 });
 cmp_ok $date_string, 'eq', '12/11/2013 06:35 PM', 'as_due_date with hours and timeformat 12hr (non-midnight time)';
+
+my $now = DateTime->now;
+is( dt_from_string, $now, "Without parameter, dt_from_string should return today" );
+
+$module_context->mock(
+    'tz',
+    sub {
+        return DateTime::TimeZone->new( name => 'Europe/Lisbon' );
+    }
+);
+
+$dt = dt_from_string('1979-04-01');
+isa_ok( $dt, 'DateTime', 'dt_from_string should return a DateTime object if a DST is given' );
+
+$module_context->mock(
+    'tz',
+    sub {
+        return DateTime::TimeZone->new( name => 'Europe/Paris' );
+    }
+);
+
+$dt = dt_from_string('2014-03-30 02:00:00');
+isa_ok( $dt, 'DateTime', 'dt_from_string should return a DateTime object if a DST is given' );
index f9a0e72..e45427e 100644 (file)
@@ -1,16 +1,17 @@
 #!/usr/bin/perl
-#
 
-use strict;
-use warnings;
+use Modern::Perl;
 use C4::Context;
 use C4::Dates;
-use Test::More tests => 5;
+use Test::More tests => 7;
+use Test::MockModule;
 
 BEGIN {
         use_ok('Koha::Template::Plugin::KohaDates');
 }
 
+my $module_context = new Test::MockModule('C4::Context');
+
 my $date = "1973-05-21";
 my $context = C4::Context->new();
 my $dateobj = C4::Dates->new();
@@ -18,7 +19,6 @@ my $dateobj = C4::Dates->new();
 my $filter = Koha::Template::Plugin::KohaDates->new();
 ok ($filter, "new()");
 
-
 $context->set_preference( "dateformat", 'iso' );
 $context->clear_syspref_cache();
 $dateobj->reset_prefformat;
@@ -40,3 +40,23 @@ $dateobj->reset_prefformat;
 
 $filtered_date = $filter->filter($date);
 is ($filtered_date,'21/05/1973', "metric conversion") or diag ("metric conversion fails $filtered_date");
+
+$module_context->mock(
+    'tz',
+    sub {
+        return DateTime::TimeZone->new( name => 'Europe/Lisbon' );
+    }
+);
+
+$filtered_date = $filter->filter('1979-04-01');
+is( $filtered_date, '01/04/1979', 'us: dt_from_string should return the valid date if a DST is given' );
+
+$module_context->mock(
+    'tz',
+    sub {
+        return DateTime::TimeZone->new( name => 'Europe/Paris' );
+    }
+);
+
+$filtered_date = $filter->filter('2014-03-30 02:00:00');
+is( $filtered_date, '30/03/2014', 'us: dt_from_string should return a DateTime object if a DST is given' );