You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

96 lines
2.3 KiB

From d744bf17b7a0e0158eb813a8605cc0d8635f8959 Mon Sep 17 00:00:00 2001
From: Dave Rolsky <autarch@urth.org>
Date: Sat, 3 May 2014 11:39:47 +0800
Subject: [PATCH] Don't leave the object in a modified state after a failed
truncate( to => 'week' )
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Petr Pisar: Ported to 1.06.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
lib/DateTime.pm | 11 ++++++++++-
t/16truncate.t | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/lib/DateTime.pm b/lib/DateTime.pm
index 1ff4c2e..a8663b2 100644
--- a/lib/DateTime.pm
+++ b/lib/DateTime.pm
@@ -1985,7 +1985,16 @@ sub set_formatter {
$self->add( days => -1 * $day_diff );
}
- return $self->truncate( to => 'day' );
+ # This can fail if the truncate ends up giving us an invalid local
+ # date time. If that happens we need to reverse the addition we
+ # just did. See https://rt.cpan.org/Ticket/Display.html?id=93347.
+ try {
+ $self->truncate( to => 'day' );
+ }
+ catch {
+ $self->add( days => $day_diff );
+ die $_;
+ };
}
else {
my $truncate;
diff --git a/t/16truncate.t b/t/16truncate.t
index 0058f50..a478760 100644
--- a/t/16truncate.t
+++ b/t/16truncate.t
@@ -5,6 +5,7 @@ use Test::Fatal;
use Test::More 0.88;
use DateTime;
+use Try::Tiny;
my %vals = (
year => 50,
@@ -233,4 +234,41 @@ my %vals = (
}
}
+{
+ my $dt = DateTime->new(
+ year => 2010,
+ month => 3,
+ day => 25,
+ hour => 1,
+ minute => 5,
+ time_zone => 'Asia/Tehran',
+ );
+
+ is(
+ $dt->day_of_week(),
+ 4,
+ 'day of week is Thursday'
+ );
+
+ my $error;
+ try {
+ $dt->truncate( to => 'week' );
+ }
+ catch {
+ $error = $_;
+ };
+
+ like(
+ $error,
+ qr/Invalid local time for date/,
+ 'truncate operation threw an error because of an invalid local datetime'
+ );
+
+ is(
+ $dt->day_of_week(),
+ 4,
+ 'day of week does not change after failed truncate() call'
+ );
+}
+
done_testing();
--
1.9.0