From 646cb2aa3a79d7b35a1673fc67cdf802e9cba515 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Tue, 3 Jun 2014 14:31:04 +0200 Subject: [PATCH] =?utf8?q?Locale::parse=5Fdate=5Fto=5Fobject:=20Unterst?= =?utf8?q?=C3=BCtzung=20f=C3=BCr=20volle=20Timestamps=20&=20explizite=20Fo?= =?utf8?q?rmate?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit …und dafür Tests. --- SL/Helper/DateTime.pm | 2 +- SL/Locale.pm | 28 ++++++++++++++---- SL/RP.pm | 8 +++--- bin/mozilla/rp.pl | 3 +- t/locale/parse_date_to_object.t | 51 +++++++++++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 12 deletions(-) create mode 100644 t/locale/parse_date_to_object.t diff --git a/SL/Helper/DateTime.pm b/SL/Helper/DateTime.pm index 3d6c78e10..94c311f14 100644 --- a/SL/Helper/DateTime.pm +++ b/SL/Helper/DateTime.pm @@ -28,7 +28,7 @@ sub to_lxoffice { } sub from_kivitendo { - return $::locale->parse_date_to_object(\%::myconfig, $_[1]); + return $::locale->parse_date_to_object($_[1]); } sub from_lxoffice { diff --git a/SL/Locale.pm b/SL/Locale.pm index a20620cdb..23a399e10 100644 --- a/SL/Locale.pm +++ b/SL/Locale.pm @@ -374,10 +374,23 @@ sub parse_date { } sub parse_date_to_object { - my $self = shift; - my ($yy, $mm, $dd) = $self->parse_date(@_); + my ($self, $string, %params) = @_; - return $yy && $mm && $dd ? DateTime->new(year => $yy, month => $mm, day => $dd) : undef; + $params{dateformat} ||= $::myconfig{dateformat} || 'yy-mm-dd'; + $params{numberformat} ||= $::myconfig{numberformat} || '1,000.00'; + my $num_separator = $params{numberformat} =~ m{,\d+$} ? ',' : '.'; + + my ($date_str, $time_str) = split m{\s+}, $string, 2; + my ($yy, $mm, $dd) = $self->parse_date(\%params, $date_str); + + my $millisecond = 0; + my ($hour, $minute, $second) = split m/:/, $time_str; + ($second, $millisecond) = split quotemeta($num_separator), $second, 2; + $millisecond = substr $millisecond, 0, 3; + $millisecond .= '0' x (3 - length $millisecond); + + return undef unless $yy && $mm && $dd; + return DateTime->new(year => $yy, month => $mm, day => $dd, hour => $hour * 1, minute => $minute * 1, second => $second * 1, nanosecond => $millisecond * 1000000); } sub format_date_object_to_time { @@ -644,9 +657,14 @@ TODO: Describe new TODO: Describe parse_date -=item C +=item C + +Parses a date and optional timestamp in C<$string> and returns an +instance of L. The date and number formats used are the ones +the user has currently selected. They can be overriden by passing them +in as parameters to this function, though. -TODO: Describe parse_date_to_object +The time stamps can have up to millisecond precision. =item C diff --git a/SL/RP.pm b/SL/RP.pm index f6d9a888c..969e8adfb 100644 --- a/SL/RP.pm +++ b/SL/RP.pm @@ -58,7 +58,7 @@ sub get_balance_starting_date { my $asofdate = shift; return unless $asofdate; - $asofdate = $::locale->parse_date_to_object(\%::myconfig, $asofdate); + $asofdate = $::locale->parse_date_to_object($asofdate); my $form = $main::form; my $dbh = $::form->get_standard_dbh; @@ -85,7 +85,7 @@ sub get_balance_starting_date { # default. my ($closedto) = selectfirst_array_query($form, $dbh, 'SELECT closedto FROM defaults'); if ($closedto) { - $closedto = $::locale->parse_date_to_object(\%::myconfig, $closedto); + $closedto = $::locale->parse_date_to_object($closedto); $closedto->subtract(years => 1) while ($asofdate - $closedto)->is_negative; $closedto->add(days => 1); }; @@ -93,11 +93,11 @@ sub get_balance_starting_date { my ($query, $startdate, $last_ob, $mindate); $query = qq|select max(transdate) from acc_trans where ob_transaction is true and transdate <= ?|; ($last_ob) = selectrow_query($::form, $dbh, $query, $::locale->format_date(\%::myconfig, $asofdate)); - $last_ob = $::locale->parse_date_to_object(\%::myconfig, $last_ob) if $last_ob; + $last_ob = $::locale->parse_date_to_object($last_ob) if $last_ob; $query = qq|select min(transdate) from acc_trans|; ($mindate) = selectrow_query($::form, $dbh, $query); - $mindate = $::locale->parse_date_to_object(\%::myconfig, $mindate); + $mindate = $::locale->parse_date_to_object($mindate); # the default method is to use all transactions ($mindate) diff --git a/bin/mozilla/rp.pl b/bin/mozilla/rp.pl index abffd9728..860d38f5e 100644 --- a/bin/mozilla/rp.pl +++ b/bin/mozilla/rp.pl @@ -1789,8 +1789,7 @@ sub generate_bwa { # if (defined ($form->{fromdate|todate}=='..')) # immer wahr if ($form->{fromdate}){ - my ($yy, $mm, $dd) = $locale->parse_date(\%myconfig, $form->{fromdate}); - my $datetime = $locale->parse_date_to_object(\%myconfig, $form->{fromdate}); + my $datetime = $locale->parse_date_to_object($form->{fromdate}); $datetime->set( month => 1, day => 1); $form->{comparefromdate} = $locale->format_date(\%::myconfig, $datetime); diff --git a/t/locale/parse_date_to_object.t b/t/locale/parse_date_to_object.t new file mode 100644 index 000000000..4a042e46c --- /dev/null +++ b/t/locale/parse_date_to_object.t @@ -0,0 +1,51 @@ +use strict; + +use Test::More; + +use lib 't'; +use Support::TestSetup; + +Support::TestSetup::login(); + +sub is_dt { + my ($string, $expected, $msg, %args) = @_; + + is($::locale->format_date_object($::locale->parse_date_to_object($string, %args), numberformat => '1000.00', dateformat => 'yy-mm-dd', precision => 'millisecond'), $expected, $msg); +} + +is($::locale->parse_date_to_object('in-valid!'), undef, 'defaults, invalid'); + +delete $::myconfig{numberformat}; +delete $::myconfig{dateformat}; + +is_dt('2014-05-31', '2014-05-31 00:00:00.000', 'defaults, no precision'); +is_dt('2014-05-31 2', '2014-05-31 02:00:00.000', 'defaults, precision hour'); +is_dt('2014-05-31 2:04', '2014-05-31 02:04:00.000', 'defaults, precision minute'); +is_dt('2014-05-31 2:04:59', '2014-05-31 02:04:59.000', 'defaults, precision second'); +is_dt('2014-05-31 02:4:59.098', '2014-05-31 02:04:59.098', 'defaults, precision millisecond'); +is_dt('2014-05-31 02:4:59.09', '2014-05-31 02:04:59.090', 'defaults, precision centisecond'); + +$::myconfig{numberformat} = '1.000,00'; +$::myconfig{dateformat} = 'dd.mm.yy'; + +is_dt('31.05.2014', '2014-05-31 00:00:00.000', 'myconfig numberformat 1.000,00 dateformat dd.mm.yy, no precision'); +is_dt('31.05.2014 2', '2014-05-31 02:00:00.000', 'myconfig numberformat 1.000,00 dateformat dd.mm.yy, precision hour'); +is_dt('31.05.2014 2:04', '2014-05-31 02:04:00.000', 'myconfig numberformat 1.000,00 dateformat dd.mm.yy, precision minute'); +is_dt('31.05.2014 2:04:59', '2014-05-31 02:04:59.000', 'myconfig numberformat 1.000,00 dateformat dd.mm.yy, precision second'); +is_dt('31.05.2014 02:4:59,098', '2014-05-31 02:04:59.098', 'myconfig numberformat 1.000,00 dateformat dd.mm.yy, precision millisecond'); + +is_dt('05/31/2014', '2014-05-31 00:00:00.000', 'myconfig numberformat 1.000,00 explicit dateformat mm/dd/yy, no precision', dateformat => 'mm/dd/yy'); +is_dt('05/31/2014 2', '2014-05-31 02:00:00.000', 'myconfig numberformat 1.000,00 explicit dateformat mm/dd/yy, precision hour', dateformat => 'mm/dd/yy'); +is_dt('05/31/2014 2:04', '2014-05-31 02:04:00.000', 'myconfig numberformat 1.000,00 explicit dateformat mm/dd/yy, precision minute', dateformat => 'mm/dd/yy'); +is_dt('05/31/2014 2:04:59', '2014-05-31 02:04:59.000', 'myconfig numberformat 1.000,00 explicit dateformat mm/dd/yy, precision second', dateformat => 'mm/dd/yy'); +is_dt('05/31/2014 02:4:59,098', '2014-05-31 02:04:59.098', 'myconfig numberformat 1.000,00 explicit dateformat mm/dd/yy, precision millisecond', dateformat => 'mm/dd/yy'); + +is_dt('05/31/2014', '2014-05-31 00:00:00.000', 'explicit numberformat 1000.00 explicit dateformat mm/dd/yy, no precision', dateformat => 'mm/dd/yy', numberformat => '1000.00'); +is_dt('05/31/2014 2', '2014-05-31 02:00:00.000', 'explicit numberformat 1000.00 explicit dateformat mm/dd/yy, precision hour', dateformat => 'mm/dd/yy', numberformat => '1000.00'); +is_dt('05/31/2014 2:04', '2014-05-31 02:04:00.000', 'explicit numberformat 1000.00 explicit dateformat mm/dd/yy, precision minute', dateformat => 'mm/dd/yy', numberformat => '1000.00'); +is_dt('05/31/2014 2:04:59', '2014-05-31 02:04:59.000', 'explicit numberformat 1000.00 explicit dateformat mm/dd/yy, precision second', dateformat => 'mm/dd/yy', numberformat => '1000.00'); +is_dt('05/31/2014 02:4:59.098', '2014-05-31 02:04:59.098', 'explicit numberformat 1000.00 explicit dateformat mm/dd/yy, precision millisecond', dateformat => 'mm/dd/yy', numberformat => '1000.00'); + +done_testing; + +1; -- 2.20.1