From 5d1177b10308997dfea5e2f05fe62627cb0be83a Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Tue, 16 Sep 2014 13:15:57 +0200 Subject: [PATCH] Bug 12669: Centralize the timezone handle into Koha::DateUtils 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). --- Koha/DateUtils.pm | 34 ++++++++++++++++++++----- Koha/Template/Plugin/KohaDates.pm | 3 +-- t/DateUtils.t | 26 ++++++++++++++++--- t/db_dependent/Koha_template_plugin_KohaDates.t | 30 ++++++++++++++++++---- 4 files changed, 76 insertions(+), 17 deletions(-) diff --git a/Koha/DateUtils.pm b/Koha/DateUtils.pm index a993ffe..129bf20 100644 --- a/Koha/DateUtils.pm +++ b/Koha/DateUtils.pm @@ -53,9 +53,9 @@ 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; - } + + my $dt; + $tz ||= C4::Context->tz; if ( !$date_format ) { $date_format = C4::Context->preference('dateformat'); } @@ -84,10 +84,32 @@ 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() ); + if ( $date_string =~ m|00:00:00$| + or $date_string =~ m|^\d{4}-\d{2}-\d{2}$| + or $date_string =~ m|^\d{4}/\d{2}/\d{2}$| ) + { + $tz = DateTime::TimeZone->new( name => 'floating' ); + } + else { + $tz = C4::Context->tz; + } + + $dt = eval { + DateTime::Format::DateParse->parse_datetime( $date_string, + $tz->name() ); + }; + if ( $@ ) { + $tz = DateTime::TimeZone->new( name => 'floating' ); + $dt = eval { + DateTime::Format::DateParse->parse_datetime( $date_string, + $tz->name() ); + }; + } + } else { + $dt = DateTime->now( time_zone => $tz ); } - return DateTime->now( time_zone => $tz ); + + return $dt; } diff --git a/Koha/Template/Plugin/KohaDates.pm b/Koha/Template/Plugin/KohaDates.pm index b4c1d8d..711255a 100644 --- a/Koha/Template/Plugin/KohaDates.pm +++ b/Koha/Template/Plugin/KohaDates.pm @@ -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 }) : diff --git a/t/DateUtils.t b/t/DateUtils.t index 9afddc1..f1faba7 100755 --- a/t/DateUtils.t +++ b/t/DateUtils.t @@ -1,11 +1,9 @@ -use strict; -use warnings; -use 5.010; +use Modern::Perl; 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 +143,23 @@ $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)'; + +$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' ); diff --git a/t/db_dependent/Koha_template_plugin_KohaDates.t b/t/db_dependent/Koha_template_plugin_KohaDates.t index f9a0e72..e45427e 100644 --- a/t/db_dependent/Koha_template_plugin_KohaDates.t +++ b/t/db_dependent/Koha_template_plugin_KohaDates.t @@ -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' ); -- 2.1.0