DatesRole: fix and expand relative dates.
- Add grouping to regex for proper |ing. - Add 'year' to relative dates. (See Chinese zodiac) - Add more tests.master
parent
d12154fdc0
commit
ffd257aa09
|
@ -39,7 +39,7 @@ my $month_regex = qr#$full_month|$short_month#;
|
|||
my $time_24h = qr#(?:(?:[0-1][0-9])|(?:2[0-3]))[:]?[0-5][0-9][:]?[0-5][0-9]#i;
|
||||
my $time_12h = qr#(?:(?:0[1-9])|(?:1[012])):[0-5][0-9]:[0-5][0-9]\s?(?:am|pm)#i;
|
||||
my $date_number = qr#[0-3]?[0-9]#;
|
||||
my $relative_days = qr#now|today|tomorrow|yesterday|(?:current|previous day)|(?:next|last week|month)#i;
|
||||
my $relative_days = qr#now|today|tomorrow|yesterday|(?:(?:current|previous|next) day)|(?:next|last) (?:week|month|year)#i;
|
||||
# Covering the ambiguous formats, like:
|
||||
# DMY: 27/11/2014 with a variety of delimiters
|
||||
# MDY: 11/27/2014 -- fundamentally non-sensical date format, for americans
|
||||
|
@ -244,8 +244,8 @@ my $descriptive_datestring = qr{
|
|||
(?:(?:$month_regex)\s(?:[0-9]{4})) | # Jan 2014, August 2000
|
||||
(?:(?:$date_number)\s?$number_suffixes?\s(?:$month_regex)) | # 18th Jan, 01 October
|
||||
(?:(?:$month_regex)\s(?:$date_number)\s?$number_suffixes?) | # Dec 25, July 4th
|
||||
(?:$month_regex) | # February, Aug
|
||||
(?:$relative_days)
|
||||
(?:$month_regex) | # February, Aug
|
||||
(?:$relative_days) # next week, last year
|
||||
}ix;
|
||||
|
||||
# Used for parse_descriptive_datestring_to_date
|
||||
|
@ -399,47 +399,52 @@ sub parse_descriptive_datestring_to_date {
|
|||
|
||||
return unless ($string && $string =~ qr/^$descriptive_datestring_matches$/);
|
||||
|
||||
my $now = DateTime->now();
|
||||
my $month = $+{'m'}; # Set in each alternative match.
|
||||
my $now = DateTime->now();
|
||||
my $month = $+{'m'}; # Set in each alternative match.
|
||||
|
||||
if (my $day = $+{'d'}) {
|
||||
return parse_datestring_to_date("$day $month ".$now->year());
|
||||
}
|
||||
elsif (my $relative_dir = $+{'q'}) {
|
||||
my $tmp_date = parse_datestring_to_date("01 $month ".$now->year());
|
||||
return parse_datestring_to_date("$day $month " . $now->year());
|
||||
} elsif (my $relative_dir = $+{'q'}) {
|
||||
my $tmp_date = parse_datestring_to_date("01 $month " . $now->year());
|
||||
# next <month>
|
||||
$tmp_date->add( years => 1) if ($relative_dir eq "next" && DateTime->compare($tmp_date, $now) != 1);
|
||||
$tmp_date->add(years => 1) if ($relative_dir eq "next" && DateTime->compare($tmp_date, $now) != 1);
|
||||
# last <month>
|
||||
$tmp_date->add( years => -1) if ($relative_dir eq "last" && DateTime->compare($tmp_date, $now) != -1);
|
||||
$tmp_date->add(years => -1) if ($relative_dir eq "last" && DateTime->compare($tmp_date, $now) != -1);
|
||||
return $tmp_date;
|
||||
}
|
||||
elsif (my $year = $+{'y'}) {
|
||||
} elsif (my $year = $+{'y'}) {
|
||||
# Month and year is the first of that month.
|
||||
return parse_datestring_to_date("01 $month $year");
|
||||
}
|
||||
elsif (my $relative_date = $+{'r'}) {
|
||||
} elsif (my $relative_date = $+{'r'}) {
|
||||
return $now if ($relative_date =~ qr/now|today|(?:current day)/);
|
||||
|
||||
my $tmp_date = $now;
|
||||
return $now if ($+{'r'} =~ qr/now|today|(current day)/);
|
||||
my @to_add;
|
||||
|
||||
$tmp_date->add( days => 1) if ($+{'r'} =~ qr/tomorrow|(next day)/);
|
||||
$tmp_date->add( days => -1) if ($+{'r'} =~ qr/yesterday|(previous day)/);
|
||||
if ($relative_date =~ qr/tomorrow|(?:next day)/) {
|
||||
@to_add = (days => 1);
|
||||
} elsif ($relative_date =~ qr/yesterday|(?:previous day)/) {
|
||||
@to_add = (days => -1);
|
||||
} elsif ($relative_date =~ qr/(?<dir>next|last) (?<unit>week|month|year)/) {
|
||||
my $unit = $+{'unit'};
|
||||
my $num = ($+{'dir'} eq 'next') ? 1 : -1;
|
||||
|
||||
if ($+{'r'} =~ qr/(next|last) (week|month)/) {
|
||||
my $num = 1;
|
||||
$num = -1 if ($1 eq "last");
|
||||
@to_add =
|
||||
($unit eq 'week') ? (days => 7 * $num)
|
||||
: ($unit eq 'month') ? (months => $num)
|
||||
: ($unit eq 'year') ? (years => $num)
|
||||
: ();
|
||||
|
||||
$tmp_date->add( days => 7*$num ) if($2 eq "week");
|
||||
$tmp_date->add( months => $num ) if($2 eq "month");
|
||||
}
|
||||
|
||||
$tmp_date->add(@to_add) if (@to_add);
|
||||
return $tmp_date;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
# single named months
|
||||
# "january" in january means the current month
|
||||
# otherwise it always means the coming month of that name, be it this year or next year
|
||||
return parse_datestring_to_date("01 ".$now->month()." ".$now->year()) if lc($now->month_name()) eq lc($month);
|
||||
my $this_years_month = parse_datestring_to_date("01 $month ".$now->year());
|
||||
$this_years_month->add( years => 1 ) if (DateTime->compare($this_years_month, $now) == -1);
|
||||
return parse_datestring_to_date("01 " . $now->month() . " " . $now->year()) if lc($now->month_name()) eq lc($month);
|
||||
my $this_years_month = parse_datestring_to_date("01 $month " . $now->year());
|
||||
$this_years_month->add(years => 1) if (DateTime->compare($this_years_month, $now) == -1);
|
||||
return $this_years_month;
|
||||
}
|
||||
}
|
||||
|
|
33
t/00-roles.t
33
t/00-roles.t
|
@ -268,6 +268,7 @@ subtest 'Dates' => sub {
|
|||
'next jan' => '01 Jan 2001',
|
||||
'last jan' => '01 Jan 2000',
|
||||
'feb 2038' => '01 Feb 2038',
|
||||
'next day' => '02 Aug 2000',
|
||||
},
|
||||
'2015-12-01T00:00:00Z' => {
|
||||
'next december' => '01 Dec 2016',
|
||||
|
@ -281,22 +282,30 @@ subtest 'Dates' => sub {
|
|||
'feb 2038' => '01 Feb 2038',
|
||||
'now' => '01 Dec 2015',
|
||||
'today' => '01 Dec 2015',
|
||||
'current day' => '01 Dec 2015',
|
||||
'next month' => '01 Jan 2016',
|
||||
},
|
||||
'2000-01-01T00:00:00Z' => {
|
||||
'feb 21st' => '21 Feb 2000',
|
||||
'11th feb' => '11 Feb 2000',
|
||||
'march 13' => '13 Mar 2000',
|
||||
'12 march' => '12 Mar 2000',
|
||||
'next week' => '08 Jan 2000',
|
||||
'last week' => '25 Dec 1999',
|
||||
'tomorrow' => '02 Jan 2000',
|
||||
'yesterday' => '31 Dec 1999',
|
||||
'feb 21st' => '21 Feb 2000',
|
||||
'11th feb' => '11 Feb 2000',
|
||||
'march 13' => '13 Mar 2000',
|
||||
'12 march' => '12 Mar 2000',
|
||||
'next week' => '08 Jan 2000',
|
||||
'last week' => '25 Dec 1999',
|
||||
'tomorrow' => '02 Jan 2000',
|
||||
'yesterday' => '31 Dec 1999',
|
||||
'last year' => '01 Jan 1999',
|
||||
'next year' => '01 Jan 2001',
|
||||
},
|
||||
'2014-10-08T00:00:00Z' => {
|
||||
'next week' => '01 Oct 2014',
|
||||
'last week' => '15 oct 2014',
|
||||
'next month' => '08 Nov 2014',
|
||||
'last month' => '08 Sep 2014'
|
||||
'next week' => '15 Oct 2014',
|
||||
'last week' => '01 Oct 2014',
|
||||
'next month' => '08 Nov 2014',
|
||||
'last month' => '08 Sep 2014',
|
||||
'next year' => '08 Oct 2015',
|
||||
'last year' => '08 Oct 2013',
|
||||
'december 2015' => '01 Dec 2015',
|
||||
'march 13' => '13 Mar 2014',
|
||||
},
|
||||
);
|
||||
foreach my $query_time (sort keys %time_strings) {
|
||||
|
|
Loading…
Reference in New Issue