Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change RFC3339_RE to accept offset like +08:00,+0800 or +08/+8 #1167

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Remove RFC3999 code and optimize testing script
  • Loading branch information
Steve Guo committed Dec 26, 2017
commit 270dfdd25ddeee43b23e50d3d6592be05ff617b3
35 changes: 16 additions & 19 deletions lib/Mojo/Date.pm
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,13 @@ use Time::Local 'timegm';

has epoch => sub {time};

my $RFC3339_RE = qr/
^(\d+)-(\d+)-(\d+)\D+(\d+):(\d+):(\d+(?:\.\d+)?) # Date and time
(?:Z|([+-])(\d+):(\d+))?$ # Offset
/xi;

my $ISO8601_RE = qr/
^(\d{4}(?!\d{2}\b)) # Years
(?:(-?)(?:(\d\d)(?:\2(\d\d))? # Calendar dates
|W(\d\d)-?([1-7])? # Week dates
|(\d{3})) # Ordinal dates
(?:[T\s](\d\d)(?:(:?)(\d\d))?(?:\9(\d\d(?:[\.,]\d+)?)?)? # Time
(?:Z|([\+-])(\d{1,2}):?(\d{2})?)?)?)?$ # Offset
^(\d{4}(?!\d{2}\b)) # Years
(?:(-?)(?:(\d\d)(?:\2(\d\d))? # Calendar dates
|W(\d\d)-?([1-7])? # Week dates
|(\d{3})) # Ordinal dates
(?:(?:T|\s+)(\d\d)(?:(:?)(\d\d))?(?:\9(\d\d(?:[\.,]\d+)?)?)? # Time
(?:Z|([\+-])(\d{1,2}):?(\d{2})?)?)?)?$ # Offset
/xi;

my @DAYS = qw(Sun Mon Tue Wed Thu Fri Sat);
Expand All @@ -41,12 +36,6 @@ sub parse {
($day, $month, $year, $h, $m, $s) = ($1, $MONTHS{$2}, $3, $4, $5, $6);
}

# RFC 3339 (1994-11-06T08:49:37Z)
elsif ($date =~ $RFC3339_RE) {
($year, $month, $day, $h, $m, $s) = ($1, $2 - 1, $3, $4, $5, $6);
$offset = (($8 * 3600) + ($9 * 60)) * ($7 eq '+' ? -1 : 1) if $7;
}

# ISO 8601 (2000-01-02 03:04:05.678+0900)
# Groups: 2000,-,01,02,undef,undef,undef,03,:,04,05.678,+,09,00
elsif ($date =~ $ISO8601_RE) {
Expand All @@ -55,11 +44,11 @@ sub parse {
$month = 0;
unless($day) {
my $days = 0;
$days += Time::Local::_is_leap_year($_)?366:365 for (1970..($year - 1));
$days += _is_leap_year($_)?366:365 for (1970..($year - 1));
my $wday_offset = ($days + 3) % 7; # first day of 1970 is 4(Thu)
$day = ($week - 1) * 7 + ($6 // 1) - $wday_offset;
}
my $n = Time::Local::_is_leap_year($year)? 29 : 28;
my $n = _is_leap_year($year)? 29 : 28;
my @m = (31,$n,31,30,31,30,31,31,30,31,30,31);
for (@m) { last if $day <= $_; $day -= $_; $month++ }
}
Expand Down Expand Up @@ -100,6 +89,14 @@ sub to_string {
$MONTHS[$month], $year + 1900, $h, $m, $s;
}

sub _is_leap_year {
return 0 if $_[0] % 4;
return 1 if $_[0] % 100;
return 0 if $_[0] % 400;

return 1;
}

1;

=encoding utf8
Expand Down
28 changes: 14 additions & 14 deletions t/mojo/date.t
Original file line number Diff line number Diff line change
Expand Up @@ -41,33 +41,33 @@ is(Mojo::Date->new(784111777.33)->to_datetime,

# ISO 8601
is(Mojo::Date->new('20140820T204500')->epoch,
1408567500, 'right epoch value');
1408567500, 'date time format yyyymmddTHHMMSS');
is(Mojo::Date->new('20140820T204500+00')->epoch,
1408567500, 'right epoch value');
1408567500, 'date time format yyyymmddTHHMMSS+00');
is(Mojo::Date->new('20140820T214500+01')->epoch,
1408567500, 'right epoch value');
1408567500, 'date time format yyyymmddTHHMMSS+HH');
is(Mojo::Date->new('20140820T221500+130')->epoch,
1408567500, 'right epoch value');
1408567500, 'date time format yyyymmddTHHMMSS+HMM');
is(Mojo::Date->new('2014-08-20 22:15:00.05+0130')->epoch,
1408567500.05, 'right epoch value');
1408567500.05, 'date time format yyyy-mm-ddTHH:MM:SS.NN+HHMM');
is(Mojo::Date->new('2014-08-20T19:15:00,06-0130')->epoch,
1408567500.06, 'right epoch value');
1408567500.06, 'date time format yyyy-mm-ddTHH:MM:SS,NN-HHMM');
is(Mojo::Date->new('2014-232T20:45:00')->epoch,
1408567500, 'right epoch value');
1408567500, 'date time format yyyy-DDDTHH:MM:SS');
is(Mojo::Date->new('2014-W34-3T20:45:00')->epoch,
1408567500, 'right epoch value');
1408567500, 'date time format yyyy-Www-DTHH:MM:SS');
is(Mojo::Date->new('2014W343T20:45:00')->epoch,
1408567500, 'right epoch value');
1408567500, 'date time format yyyyWwwDTHH:MM:SS');
is(Mojo::Date->new('2014-01')->epoch,
1388534400, 'right epoch value');
1388534400, 'date format yyyy-mm');
is(Mojo::Date->new('2014-01-01')->epoch,
1388534400, 'right epoch value');
1388534400, 'date format yyyy-mm-dd');
is(Mojo::Date->new('2014-01-01T00')->epoch,
1388534400, 'right epoch value');
1388534400, 'date time format yyyy-mm-ddTHH');
is(Mojo::Date->new('2014-01-01T00:00')->epoch,
1388534400, 'right epoch value');
1388534400, 'date time format yyyy-mm-ddTHH:MM');
is(Mojo::Date->new('2014-01-01T00:00+00')->epoch,
1388534400, 'right epoch value');
1388534400, 'date time format yyyy-mm-ddTHH:MM+HH');

# Special cases
is(Mojo::Date->new('Sun , 06-Nov-1994 08:49:37 UTC')->epoch,
Expand Down