Skip Menu |

This queue is for tickets about the Date-RangeParser-EN CPAN distribution.

Report information
The Basics
Id: 94912
Status: resolved
Priority: 0/
Queue: Date-RangeParser-EN

People
Owner: aquilina [...] cpan.org
Requestors: GSG [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: (no value)
Fixed in: (no value)



Subject: Add support for parsing "before" and "after"
English date parsing isn't complete without support for parsing things like "after today". A patch to add such support is attached.
Subject: range_parser_before_and_after.patch
diff --git a/Date-RangeParser-EN-0.06/Changes b/Date-RangeParser-EN-0.06/Changes index f5a614a..9ae2856 100644 --- a/Date-RangeParser-EN-0.06/Changes +++ b/Date-RangeParser-EN-0.06/Changes @@ -1,5 +1,15 @@ Revision history for Perl extension Date::RangeParser::EN +0.07 Fri Apr 18 12:26:13 2014 + - Add support for infinite datetimes + - Add support for parsing + * "before [element]" + * "< [element]" + * "<= [element]" + * "after [element]" + * "> [element]" + * ">= [element]" + 0.06 Mon Nov 12 19:25:17 2012 - Fix bug where "31st of last month" in 11/2012 would not parse properly. diff --git a/Date-RangeParser-EN-0.06/lib/Date/RangeParser/EN.pm b/Date-RangeParser-EN-0.06/lib/Date/RangeParser/EN.pm index 4122538..43411d2 100644 --- a/Date-RangeParser-EN-0.06/lib/Date/RangeParser/EN.pm +++ b/Date-RangeParser-EN-0.06/lib/Date/RangeParser/EN.pm @@ -104,6 +104,13 @@ At the very least, this given class must implement a C<new> method that accepts This gives you the freedom to set your time zones and such however you need to. +=item * B<infinite_past_class> +=item * B<infinite_future_class> + +By default, Date::RangeParser::EN uses DateTime::Infinite::Past and DateTime::Infinite::Future to create open-ended ranges (for example "after today"). If you have extended these classes, you may pass the corresponding names in. + +The given classes must implement a C<new> method that accepts no arguments. + =item * B<now_callback> By default, Date::RangeParser::EN uses DateTime->now to determine the current date/time for calculations. If you need to work with a different time (for instance, if you need to adjust for time zones), you may pass a callback (code reference) which returns a DateTime object. @@ -267,6 +274,20 @@ More formally, this will parse the following kinds of date strings: RANGE-RANGE : the very start of the first range to the very end of the second 10/10-10/20 (ranges must not contain hyphens, "-") + before ELEMENT : all dates before the very start of the date specified in the ELEMENT + < ELEMENT + before today + + <= ELEMENT : all dates up to the very end of the date specified in the ELEMENT + <= today + + after ELEMENT : all dates after the very end of the date specified in the ELEMENT + > ELEMENT + after next Tuesday + + >= ELEMENT : the date specified in the ELEMENT to the end of forever + >= this Friday + since ELEMENT : the date specified in the ELEMENT to the end of the current day since last Sunday @@ -647,6 +668,36 @@ sub parse_range (undef, $end) = $self->parse_range($second); } + elsif ($string =~ /^(?:before|<) /i) { + $string =~ s/^(?:before|<) //i; + ($end) = $self->parse_range($string); + + if ( defined $end ) { + $beg = $self->_infinite_past_class->new(); + $end = $end->subtract(seconds => 1); + } + } + elsif ($string =~ /^<= /) { + $string =~ s/^<= //; + $beg = $self->_infinite_past_class->new(); + ($end) = $self->parse_range($string); + } + + elsif ($string =~ /^(?:after|>) /i) { + $string =~ s/^(?:after|>) //i; + (undef, $beg) = $self->parse_range($string); + + if ( defined $beg ) { + $beg = $beg->add(seconds => 1); + $end = $self->_infinite_future_class->new(); + } + } + elsif ($string =~ /^>= /) { + $string =~ s/^>= //; + ($beg) = $self->parse_range($string); + $end = $self->_infinite_future_class->new(); + } + elsif ($string =~ /^since /i) { $string =~ s/^since //i; ($beg) = $self->parse_range($string); @@ -655,8 +706,6 @@ sub parse_range $end = $self->_now()->clone->set(hour => 23, minute => 59, second => 59); } - # TODO: Support "after [date]". This requires handling of infinite dates. - # See if this is a range between two other dates separated by - elsif ($string !~ /^\d+-\d+$/ and $string =~ /^[^-]+-[^-]+$/) { @@ -707,6 +756,16 @@ sub _datetime_class { return $self->{datetime_class} || 'DateTime'; } +sub _infinite_future_class { + my $self = shift; + return $self->{infinite_future_class} || 'DateTime::Infinite::Future'; +} + +sub _infinite_past_class { + my $self = shift; + return $self->{infinite_past_class} || 'DateTime::Infinite::Past'; +} + sub _parse_date_manip { my ($self, $val) = @_; @@ -810,7 +869,7 @@ Thanks to Sterling Hanenkamp for adding support for explicit date ranges, improv =head1 COPYRIGHT AND LICENSE -Copyright (C) 2012 Grant Street Group. +Copyright (C) 2012-2014 Grant Street Group. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/Date-RangeParser-EN-0.06/t/01-parse_range.t b/Date-RangeParser-EN-0.06/t/01-parse_range.t index 0adb817..fe0318d 100644 --- a/Date-RangeParser-EN-0.06/t/01-parse_range.t +++ b/Date-RangeParser-EN-0.06/t/01-parse_range.t @@ -390,6 +390,67 @@ my @tests = ( as_of => '2012-11-12', beg => '12/31/2012 12:00AM', end => '12/31/2012 11:59PM', + }, { + date_range_string => 'before 4/18/2014', + as_of => '2014-04-18', + beg => '-inf', + end => '04/17/2014 11:59PM', + }, { + date_range_string => '< 4/18/2014', + as_of => '2010-01-28', + beg => '-inf', + end => '04/17/2014 11:59PM', + }, { + date_range_string => '<= 12/25/2013', + as_of => '2014-04-18', + beg => '-inf', + end => '12/25/2013 12:00AM', + }, { + date_range_string => 'after 2/5/1990', + as_of => '2014-04-18', + beg => '02/06/1990 12:00AM', + end => 'inf', + }, { + date_range_string => '> 2/5/1990', + as_of => '2010-01-28', + beg => '02/06/1990 12:00AM', + end => 'inf', + }, { + date_range_string => '>= 07/04/2776', + as_of => '1776-07-04', + beg => '07/04/2776 12:00AM', + end => 'inf', + }, { + # "after X" means "after the end of X" + # "after today" extends into infinity (it doesn't end) + # thus "after after today" means "after the end of infinity" + # and begins in infinity :) + date_range_string => 'after after today', + as_of => '2000-01-01', + beg => 'inf', + end => 'inf', + }, { + date_range_string => 'before before today', + as_of => '2000-01-01', + beg => '-inf', + end => '-inf', + }, { + date_range_string => 'before after today', + as_of => '2000-01-01', + beg => '-inf', + end => '01/01/2000 11:59PM', + }, { + # "since" truncates ->{end} to the end of the as_of date + date_range_string => 'since before 01/01/3000', + as_of => '2000-01-01', + beg => '-inf', + end => '01/01/2000 11:59PM', + }, { + # this isn't really a range, but that's expected + date_range_string => 'after after today - before before today', + as_of => '2000-01-01', + beg => 'inf', + end => '-inf', } ); @@ -414,8 +475,19 @@ for my $test (@tests) ok(defined $beg, "Beginning date for $test->{date_range_string} is defined"); ok(defined $end, "End date for $test->{date_range_string} is defined"); - cmp_ok($beg->strftime("%m/%d/%Y %I:%M%p"), 'eq', $test->{beg}, "Beginning date ok for $test->{date_range_string}"); - cmp_ok($end->strftime("%m/%d/%Y %I:%M%p"), 'eq', $test->{end}, "Ending date ok for $test->{date_range_string}"); + # stftime makes no sense on infinite times + if ( $beg->is_infinite ) { + cmp_ok( "$beg", 'eq', $test->{beg}, "Beginning date ok for $test->{date_range_string}"); + } + else { + cmp_ok($beg->strftime("%m/%d/%Y %I:%M%p"), 'eq', $test->{beg}, "Beginning date ok for $test->{date_range_string}"); + } + if ( $end->is_infinite ) { + cmp_ok( "$end", 'eq', $test->{end}, "Beginning date ok for $test->{date_range_string}"); + } + else { + cmp_ok($end->strftime("%m/%d/%Y %I:%M%p"), 'eq', $test->{end}, "Ending date ok for $test->{date_range_string}"); + } }; }
On Mon Apr 21 13:12:53 2014, GSG wrote: Show quoted text
> English date parsing isn't complete without support for parsing things > like "after today". A patch to add such support is attached.
Thanks for the patch, GSG! This was pulled into Date-RangeParser-EN 0.07, which should hit CPAN momentarily. Best, Mike
On Fri Apr 25 14:13:01 2014, AQUILINA wrote: Show quoted text
> On Mon Apr 21 13:12:53 2014, GSG wrote:
> > English date parsing isn't complete without support for parsing > > things > > like "after today". A patch to add such support is attached.
> > Thanks for the patch, GSG! > > This was pulled into Date-RangeParser-EN 0.07, which should hit CPAN > momentarily. > > Best, > > Mike