Date::RangeParser::EN - Parser for plain English date/time range strings
use Date::RangeParser::EN; my $parser = Date::RangeParser::EN->new; my ($begin, $end) = $parser->parse_range("this week");
Parses plain-English strings representing date/time ranges
Returns a new instance of Date::RangeParser::EN.
Takes an optional hash of parameters:
datetime_class
By default, Date::RangeParser::EN returns two DateTime objects representing the beginning and end of the range. If you use a subclass of DateTime (or another module that implements the DateTime API), you may pass the name of this class to use it instead.
At the very least, this given class must implement a new method that accepts a hash of arguments, where the following keys will be set:
new
year month day hour minute second
This gives you the freedom to set your time zones and such however you need to.
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.
Accepts a string representing a plain-English date range, for instance:
today
this week
the past 2 months
next Tuesday
two weeks ago
the next 3 hours
the 3rd of next month
the end of this month
More formally, this will parse the following kinds of date strings:
NUMBER : ordinary number (1) PERIOD : one of: hour, day, week, month, quarter, or year (or the plural of these) WEEKDAY : one of: Monday, Tuesday, Wedensday, Thursday, Friday, Saturday, or Sunday CARDINAL : a cardinal number (21st) or the word for that number (twenty-first) or end MONTH : a month name: January, Feburary, March, April, May, June, July August, September, October, November, or Decmeber or any 3-letter abbreviation YEAR : a 4-digit year (2-digits will not work) RANGE : any date range that can be parsed by parse_range today : today, midnight to midnight this PERIOD : the current period, start to end this month current PERIOD : the current period, start to end current year this WEEKDAY : the WEEKDAY that is in the current week, midnight to midnight this Monday NUMBER PERIOD ago : past date relative to now until now 3 days ago past NUMBER PERIOD : past date relative to now until now past 2 weeks last NUMBER PERIOD : past date relative to now until now last 6 hours past NUMBER WEEKDAY : the weekday a number of weeks before now until now past 4 Saturdays NUMBER WEEKDAY ago : the weekday a number of weeks before now until now 3 Fridays ago yesterday : yesterday, midnight to midnight last WEEKDAY : the WEEKDAY that is in the week prior to this, midnight to midnight last Wednesday previous WEEKDAY : the WEEKDAY that is in the week prior to this, midnight to midnight previous Friday past WEEKDAY : the WEEKDAY that is in the week prior to this, midnight to midnight past Tuesday this past WEEKDAY : the WEEKDAY that is in the week prior to this, midnight to midnight this past Saturday coming WEEKDAY : the WEEKDAY that is in the week after this, midnight to midnight coming Monday this coming WEEKDAY : the WEEKDAY that is in the week after this, midnight to midnight this coming Thursday NUMBER PERIOD hence : now to a future date relative to now 4 months hence NUMBER PERIOD from now : now to a future date relative to now 6 days from now next NUMBER PERIOD : now to a future date relative to now next 7 years tomorrow : tomorrow, midnight to midnight next NUMBER WEEKDAY : the WEEKDAY that is in a number of weeks after this, midnight to midnight next 4 Sundays CARDINAL of this month : the specified day of the current month, midnight to midnight 14th of this month CARDINAL of last month : the specified day of the previous month, midnight to midnight 31st of last month CARDINAL of next month : the specified day of the month following this, midnight to midnight 3rd of next month CARDINAL of NUMBER months ago : the specified day of a previous month, midnight to midnight 12th of 2 months ago CARDINAL of NUMBER months from now : the specified day of a following month, midnight to midnight 7th of 22 months from now CARDINAL of NUMBER months hence : the specified day of a following month, midnight to midnight 22nd of 6 months hence MONTH : the named month of the current year, 1st to last day August this MONTH : the named month of the current year, 1st to last day this Sep last MONTH : the named month of the previous year, 1st to last day last January next MONTH : the named month of the next year, 1st to last day next Dec MONTH YEAR : the named month of the named year, 1st to last day June 1969 RANGE to RANGE : the very start of the first range to the very end of the second Tuesday to Next Saturday RANGE thru RANGE : the very start of the first range to the very end of the second 2 hours ago thru the next 6 hours RANGE through RANGE : the very start of the first range to the very end of the second August through December RANGE - RANGE : the very start of the first range to the very end of the second 9-1-2012 - 9-30-2012 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, "-")
Anything else is parsed by Date::Manip. If Date::Manip is unable to parse the date given either, then the dates returned will be undefined.
Also, when parsing:
The word "the" will always be ignored and can appear anywhere.
Cardinal numbers may be spelled out as words, i.e. "September first" instead of "September 1st".
Any plural or singular period shown above can be used with the opposite.
All dates are parsed relative to the parser's notion of now. You can control this by setting the now_callback option on the constructor.
Returns two DateTime objects, reprensenting the beginning and end of the range.
There's a lot more that this module could handle. A few items that come to mind:
More testing to make sure certain date configurations are handled, like start of week.
Handle Unicode in places where such handling makes sense (like hyphen detection)
Allow full words instead of digits ("two weeks ago" vs "2 weeks ago")
Allow "between" for ranges ("between last February and this Friday") in addition to "to/through" ranges
This module is US English-centric (hence the "EN") and might do some things wrong for other variants of English and a generic Date::RangeParser interface could be made to allow for other languages to be parsed this way.
Date::RangeParser
Depends on Date::Manip. This may or may not be a good thing.
DateTime, Date::Manip
This module was authored by Grant Street Group (http://grantstreet.com), which was kind enough to give it back to the Perl community.
The CPAN distribution is maintained by Michael Aquilina (aquilina@cpan.org).
Copyright (C) 2012 Grant Street Group.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
To install Date::RangeParser::EN, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Date::RangeParser::EN
CPAN shell
perl -MCPAN -e shell install Date::RangeParser::EN
For more information on module installation, please visit the detailed CPAN module installation guide.