diff -rupN DateTime-Incomplete-0.07/lib/DateTime/Incomplete.pm DateTime-Incomplete/lib/DateTime/Incomplete.pm
--- DateTime-Incomplete-0.07/lib/DateTime/Incomplete.pm 2012-08-24 10:46:22.000000000 +0100
+++ DateTime-Incomplete/lib/DateTime/Incomplete.pm 2013-07-30 16:15:43.824501006 +0100
@@ -635,9 +635,31 @@ sub to_datetime
{
$result->set_time_zone( $value );
next;
push @params, ( $key => $value );
}
+
+ # See CPAN bug:
https://rt.cpan.org/Ticket/Display.html?id=87442
+ if(
+ ( 28 < $result->day_of_month )
+ &&
+ ( $self->has('month') )
+ &&
+ ( ! $self->has('day') )
+ )
+ {
+ # Find out which was the last day of the supplied month in the supplied
+ # year, (or this year if none is specified)
+ my $year = $self->year // DateTime->now()->year();
+ my $last_of_that_month = DateTime->last_day_of_month(
+ 'year' => $year, 'month' => $self->month);
+
+ if( $last_of_that_month->day_of_month() < $result->day_of_month )
+ {
+ push @params, ( 'day' => $last_of_that_month->day_of_month() );
+ }
+ }
+
$result->set( @params );
return $result;
}
diff -rupN DateTime-Incomplete-0.07/t/04base_overflow.t DateTime-Incomplete/t/04base_overflow.t
--- DateTime-Incomplete-0.07/t/04base_overflow.t 2009-07-08 20:53:13.000000000 +0100
+++ DateTime-Incomplete/t/04base_overflow.t 2013-07-30 16:16:04.144896682 +0100
@@ -2,7 +2,7 @@
use strict;
-use Test::More tests => 12;
+use Test::More tests => 21;
use DateTime;
use DateTime::Incomplete;
@@ -34,8 +34,60 @@ use DateTime::Incomplete;
# 29 feb 2009 -> to_datetime fails...
{
my $dti = DateTime::Incomplete->new( month => 2, day => 29, year=>2000);
- ok($dti->ymd(), "2000-02-29");
- ok($dti->to_datetime(), "29 feb 2000");
+ is($dti->ymd(), "2000-02-29", 'ymd() works for 29th Feb 2000');
+ is_deeply(
+ $dti->to_datetime(),
+ DateTime->last_day_of_month(year=>2000,month=>2),
+ "to_datetime() works for 29 feb 2000"
+ );
+}
+
+# Also broken if the day of the month is not specified.
+# CPAN bug:
https://rt.cpan.org/Ticket/Display.html?id=87442
+{
+ my $as_datetime = undef;
+ my $this_year = DateTime->now()->year();
+
+ # Febuary only has 28 days.
+ my $dti = DateTime::Incomplete->new( month => 2); # year and day undef
+ is($dti->ymd(), "xxxx-02-xx", 'ymd() works for Feb (unknown day & year)');
+
+ # Base date for a month with 31 days.
+ my $base = DateTime->last_day_of_month(year=>2010,month=>1);
+
+ eval{ $as_datetime = $dti->to_datetime(base=>$base) };
+ ok( !($@), 'Can call to_datetime() for feb with a base date of the 31st of a month ..');
+
+ is_deeply(
+ $as_datetime,
+ DateTime->last_day_of_month(year=>2010,month=>2),
+ ".. And the returned DateTime is valid and as expected.",
+ );
+
+ # Specify the year.
+ $dti->set(year=>2001); # day still undef
+ is($dti->ymd(), "2001-02-xx", 'ymd() works for Feb 2001 (unknown day)');
+
+ eval{ $as_datetime = $dti->to_datetime(base=>$base) };
+ ok( !($@), 'Can call to_datetime() for feb with a base date of the 31st of a month ..');
+
+ is_deeply(
+ $as_datetime,
+ DateTime->last_day_of_month(year=>2001,month=>2),
+ ".. And the returned DateTime is valid and as expected.",
+ );
+
+ # Specify only the year.
+ $dti = DateTime::Incomplete->new( year => 2001); # month and day undef
+ is($dti->ymd(), "2001-xx-xx", 'ymd() works for 2001 (unknown month & day)');
+ eval{ $as_datetime = $dti->to_datetime(base=>$base) };
+ ok( !($@), 'Can call to_datetime() with a base date of the 31st of a month ..');
+
+ is_deeply(
+ $as_datetime,
+ DateTime->last_day_of_month(year=>2001,month=>1),
+ ".. And the returned DateTime is valid and as expected.",
+ );
}
# Test: require day=30