Skip to content
Open
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
43 changes: 42 additions & 1 deletion lib/DateTime/Parse.pm6
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ my class X::DateTime::CannotParse is Exception {
class DateTime::Parse is DateTime {
grammar DateTime::Parse::Grammar {
token TOP {
<dt=rfc3339-date> | <dt=rfc1123-date> | <dt=rfc850-date> | <dt=rfc850-var-date> | <dt=rfc850-var-date-two> | <dt=asctime-date>
| <dt=rfc3339-date>
| <dt=rfc1123-date>
| <dt=rfc2822-date>
| <dt=rfc850-date>
| <dt=rfc850-var-date>
| <dt=rfc850-var-date-two>
| <dt=asctime-date>
}

token rfc3339-date {
Expand All @@ -21,6 +27,10 @@ class DateTime::Parse is DateTime {
<part=.partial-time> <offset=.time-offset>
}

token time3 {
<part=.time> <.SP> <offset=.time-offset2>
}

token partial-time {
<hour=.D2> ':' <minute=.D2> ':' <second=.D2> <frac=.time-secfrac>?
}
Expand All @@ -33,6 +43,10 @@ class DateTime::Parse is DateTime {
[ 'Z' | 'z' | <offset=.time-numoffset>]
}

token time-offset2 {
<sign=[+-]> <hour=.D2> <minute=.D2>
}

token time-numoffset {
<sign=[+-]> <hour=.D2> ':' <minute=.D2>
}
Expand All @@ -53,6 +67,10 @@ class DateTime::Parse is DateTime {
<.wkday> ',' <.SP> <date=.date1> <.SP> <time> <.SP> <gmtUtc>
}

token rfc2822-date {
<.wkday> ',' <.SP> <date=.date6> <.SP> <time=.time3>
}

token rfc850-date {
<.weekday> ',' <.SP> <date=.date2> <.SP> <time> <.SP> <gmtUtc>
}
Expand Down Expand Up @@ -93,6 +111,10 @@ class DateTime::Parse is DateTime {
<day=.D2> '-' <month> '-' <year=.D4-year>
}

token date6 { # e.g., 02 Jun 1982 or 2 Jun 1982
<day> <.SP> <month> <.SP> <year=.D4-year>
}

token time {
<hour=.D2> ':' <minute=.D2> ':' <second=.D2>
}
Expand Down Expand Up @@ -147,6 +169,10 @@ class DateTime::Parse is DateTime {
make DateTime.new(|$<date>.made, |$<time>.made)
}

method rfc2822-date($/) {
make DateTime.new(|$<date>.made, |$<time>.made)
}

method rfc850-date($/) {
make DateTime.new(|$<date>.made, |$<time>.made)
}
Expand Down Expand Up @@ -192,6 +218,10 @@ class DateTime::Parse is DateTime {
self!genericDate($/);
}

method date6($/) { # e.g. 1996-12-19
self!genericDate($/);
}

my %timezones =
UTC => 0,
GMT => 0,
Expand Down Expand Up @@ -228,6 +258,16 @@ class DateTime::Parse is DateTime {
make %res;
}

method time3($/) {
my $p = $<part>;
my $offset = 0;
if ~$<offset><sign> eq '-' {
$offset = 3600 * ~$<offset><hour>.Int;
$offset += 60 * ~$<offset><minute>.Int;
}
my %res = hour => ~$p<hour>, minute => ~$p<minute>, second => ~$p<second>, timezone => -$offset;
make %res;
}
my %wkday = Mon => 0, Tue => 1, Wed => 2, Thu => 3, Fri => 4, Sat => 5, Sun => 6;
method wkday($/) {
make %wkday{~$/}
Expand Down Expand Up @@ -287,6 +327,7 @@ DateTime::Parse - DateTime parser
=head2 Available formats:

=item rfc1123
=item rfc2822
=item rfc850
=item asctime

Expand Down
5 changes: 5 additions & 0 deletions t/01-basic.t
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use DateTime::Parse;
plan *;

my $rfc1123 = 'Sun, 06 Nov 1994 08:49:37 GMT';
my $rfc2822 = 'Sun, 06 Nov 1994 08:49:37 -0800';
my $bad = 'Bad, 06 Nov 1994 08:49:37 GMT';
my $rfc850 = 'Sunday, 06-Nov-94 08:49:37 GMT';
my $rfc850v = 'Sun 06-Nov-1994 08:49:37 GMT';
Expand All @@ -20,7 +21,11 @@ is DateTime::Parse.new('08:49:37', :rule<time>).sort,
is DateTime::Parse.new($rfc1123),
DateTime.new(:year(1994), :month(11), :day(6), :hour(8), :minute(49), :second(37)),
'parse string gives correct DateTime object';
is DateTime::Parse.new($rfc2822),
DateTime.new(:year(1994), :month(11), :day(6), :hour(8), :minute(49), :second(37), :timezone(-28800)),
'parse string gives correct DateTime object';
ok DateTime::Parse::Grammar.parse($rfc1123)<rfc1123-date>, "'Sun, 06 Nov 1994 08:49:37 GMT' is recognized as rfc1123-date";
ok DateTime::Parse::Grammar.parse($rfc2822)<rfc2822-date>, "'$rfc2822' is recognized as rfc2822-date";
throws-like qq[ DateTime::Parse.new('$bad') ], X::DateTime::CannotParse, invalid-str => $bad;
ok DateTime::Parse::Grammar.parse($rfc850)<rfc850-date>, "'$rfc850' is recognized as rfc850-date";
nok DateTime::Parse::Grammar.parse($rfc850v)<rfc850-date>, "'$rfc850v' is NOT recognized as rfc850-date";
Expand Down