Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/HTTP/Date.pm
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,12 @@ The function is able to parse the following formats:
The parser ignores leading and trailing whitespace. It also allow the
seconds to be missing and the month to be numerical in most formats.

Numeric-only dates use day/month/year ordering (the ISO and common
European convention), not the US month/day/year ordering. So
"3/4/2014" is parsed as 4 March 2014, and a US-style date such as
"3/13/2014" returns undef because 13 is not a valid month. To parse
US-style dates, swap the first two fields before calling parse_date().

If the year is missing, then we assume that the date is the first
matching date I<before> current month. If the year is given with only
2 digits, then parse_date() will select the century that makes the
Expand Down
39 changes: 39 additions & 0 deletions t/numeric-date-order.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!perl

use strict;
use warnings;

use Test::More;
use HTTP::Date qw(str2time parse_date);

# Regression/characterization test for GitHub #10 (rt.cpan.org #94151).
#
# Numeric-only slash dates are parsed in day/month/year order (the ISO and
# common European convention), NOT US month/day/year order. This is a
# deliberate, documented contract: changing it would silently re-interpret
# existing dates for every downstream caller.
#
# So '3/12/2014' is 12 March-style ordering => day 3, month 12 (December),
# and '3/13/2014' is rejected because 13 is not a valid month.

is(
str2time( '3/12/2014 0:00', 'GMT' ),
str2time( '3 Dec 2014 0:00', 'GMT' ),
'numeric N/N/YYYY uses day/month order: 3/12 == 3 December'
);

is( str2time( '3/13/2014 0:00', 'GMT' ),
undef, 'second field is the month: 13 is invalid, so undef' );

is( str2time( '13/3/2014 0:00', 'GMT' ),
str2time( '13 Mar 2014 0:00', 'GMT' ),
'day may exceed 12: 13/3 == 13 March' );

# parse_date reports the same day/month ordering.
is_deeply(
[ ( parse_date('3/12/2014') )[ 0, 1, 2 ] ],
[ 2014, 12, 3 ],
'parse_date(3/12/2014) => year 2014, month 12, day 3'
);

done_testing;
Loading