Date::Interval - handling of temporal intervals based on Date::Manip
Copyright (C) 1997 by Kristian Torp, <torp@cs.auc.dk>
This program is free software. You can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed AS IS in the hope that it will be useful, but WITHOUT ANY WARRANTY. See the GNU General Public License for more details.
Description: Sets the default <interval type> Input: <interval type> Output: none
Description: Gets the default <interval type> Input: none Output: <interval type>
Description: Sets the default <display format> Input: <display format> Output: none
Description: Gets the default <display format> Input: none Output: <display format>
Description: Constructor Input: <start value> <stop value> [<interval type>] Output: reference
Description: Returns the Length of an interval in Date::Manip format Input: none Output: <delta>
Description: Returns the length of an interval in string format Input: none Output: string
Description: Returns the interval in string format Input: none Output: string
Description: Returns the <start value> Input: none Output: <date>
Description: Returns the <stop value> Input: none Output: <date>
Description: Checks if two intervals overlap Input: <interval> Output: <boolean>
Description: Return the overlap of two intervals Input: <interval> Output: <interval> | undef
Description: Examines if interval is before Input: <interval> Output: <boolean>
Description: Examines if intervals meets Input: <interval> Output: <boolean>
Description: Examines if two intervals left overlap Input: <interval> Output: <boolean>
Description: Examines if two intervals right overlap Input: <interval> Output: <boolean>
Description: Examines if two intervals during overlap Input: <interval> Output: <boolean>
Description: Examines if two intervals totally overlap Input: <interval> Output: <boolean>
Description: Examines if two intervals extends Input: <interval> Output: <boolean>
Description: Examines if two intervals after Input: <interval> Output: <boolean>
Description: Describes in text how intervals overlaps Input: <interval> Output: to screen
Description: Return how intervals overlap in Allen´s terminology Input: <interval> Output: to screen
Description: Examines if intervals Allen before Input: <interval> Output: <boolean>
Description: Examines if intervals Allen meets Input: <interval> Output: <boolean>
Description: Examines if intervals Allen left overlaps Input: <interval> Output: <boolean>
Description: Examines if intervals Allen left covers Input: <interval> Output: <boolean>
Description: Examines if intervals Allen covers Input: <interval> Output: <boolean>
Description: Examines if intervals Allen starts Input: <interval> Output: <boolean>
Description: Examines if intervals Allen equals Input: <interval> Output: <boolean>
Description: Examines if intervals Allen right covers Input: <interval> Output: <boolean>
Description: Examines if intervals Allen during Input: <interval> Output: <boolean>
Description: Examines if intervals Allen finishes Input: <interval> Output: <boolean>
Description: Examines if intervals Allen right overlaps Input: <interval> Output: <boolean>
Description: Examines if intervals Allen extends Input: <interval> Output: <boolean>
Description: Examines if intervals Allen after Input: <interval> Output: <boolean>
Description: Initization of new instances Input: <start value> <stop value> [<interval type>] Output: none
Description: Initization of new empty instance Input: none Output: empty <interval>
Description: Sets the <interval type> Input: <interval type> Output: <boolean>
Description: Sets the interval brackets Input: <interval end> <interval end> Output: <boolean>
Description: Examines how intervals overlaps Input: <interval> Output: <overlap type> || FALSE
Description: Finds how intervals overlap in Allen terminology Input: <interval> Output: <Allen overlap type>
Description: + operator. If two intervals overlaps the union is returned Input: <interval> <interval> Output: <interval> || undefined
Description: - operator. If two intervals overlaps the intersection is returned Input: <interval> <interval> Output: <interval> [ <interval> ] || undefined
Description: < operator. Input: <interval> <interval> Output: <boolean>
Description: > operator. Input: <interval> <interval> Output: <boolean>
Description: == operator. Input: <interval> <interval> Output: <boolean>
Description: != operator. Input: <interval> <interval> Output: <boolean>
Description: <=> operator. Use ONLY for sorting because based on the start value Input: <interval> <interval> Output: -1 || 0 || 1
Description: For strinifying an interval Input: <interval> Output: string
Description: Converts a string to an <end point> Input: string Output: <end point> <value type>
Description: Converts <end point> to a date Input: <fix clock> <value type> <end point> [<start date value type> <start date>] Output: <date>
Description: Converts an <end point> to a string Input: <boolean> Output: string
Description: Converts an <end point> to a string Input: <value type> <end point> Output: string
use Date::Interval; ### class methods ### Date::Interval->setDefaultIntervalType ($Date::Interval::OPEN_INT); $int_open = new Date::Interval ("10-10-1997", "10-20-1997"); print "$int_open\n" # prints '(10-10-1997, 10-20-1997) $nDefaultType = Date::Interval->getDefaultIntervalType; ### constructor ## $i1 = new Date::Interval ("10-30-1997", "12-01-1998"); $i2 = new Date::Interval ("01-20-1996", "11-01-1997", $Date::Interval::RIGHT_OPEN_INT); use Date::Manip; $date1 = &ParseDate ("10-10-1997"); $date2 = &ParseDate ("10-15-1997"); $int = new Date::Interval ($d1, $d2); ### Overload operators ### $i3 = $i1 + $i2; # + gives the sum of intervals if the overlap print "$i3\n"; # prints '[01-20-1997, 12-01-1998)' $i4 = $i1 - $i2; # - gives difference of intervals of intervals print "$i4\n"; # prints '[11-01-1997, 12-01-1998)' $i5 = $i1 - $i1; print "$i5\n"; # prints '<empty>' ### <Allen overlap type> ### $X = new Date::Interval (<parameters>); $Y = new Date::Interval (<parameters>); ### relationship between intervals ### $Y->AllenBefore ($X); YYYYYY XXXXXX $Y->AllenMeets ($X); YYYYYYXXXXXX $Y->AllenLeftOverlaps ($X); XXXXXX YYYYYY $Y->AllenLeftCovers ($X); XXXXXX YYYYYYYYY $Y->AllenCovers ($X); XXXXXX YYYYYYYYYYYY $Y->AllenStarts ($X); XXXXXX YYY $Y->AllenEquals ($X); XXXXXX YYYYYY $Y->AllenRightCovers ($X); XXXXXX YYYYYYYYY $Y->AllenDuring ($X); XXXXXX YYYY $Y->AllenFinishes ($X); XXXXXX YYYY $Y->AllenRightOverlaps ($X); XXXXXX YYYYYY $Y->AllenExtends ($X); XXXXXXYYYYYY $Y->AllenAfter ($X): XXXXXX YYYYYY ### <overlap type> ### $Y->before ($X) same as $Y->AllenBefore ($X) $Y->meets ($X) same as $Y->AllenMeets ($X) $Y->leftOverlaps ($X) same as $Y->AllenLeftOverlaps ($X) or $Y->AllenStarts ($X) $Y->totalOverlaps ($X) same as $Y->AllenCovers ($X) or $Y->AllenLeftCovers ($X) or $Y->AllenRightCovers ($X) or $Y->AllenEquals ($X) $Y->rightOverlaps ($X) same as $Y->AllenFinishes ($X) or $Y->AllenRightCovers $Y->during ($X) same as $Y->AllenDuring ($X) $Y->extends ($X) same as $Y->AllenExtends ($X) $Y->after ($X) same as $Y->AllenAfter ($X) ### <interval type> ### $closed_int = new Interval ("10-10-1997", "10-20-1997", $CLOSED_INT); print "$closed_int\n"; # prints [10-10-1997, 10-20-1997] $left_open_int = new Interval ("10-10-1997", "10-20-1997", $LEFT_OPEN_INT); print "$left_open_int\n"; # prints (10-10-1997, 10-20-1997] $right_open_int = new Interval ("10-10-1997", "10-20-1997", $RIGHT_OPEN_INT); print "$right_open_int\n"; # prints [10-10-1997, 10-20-1997) $open_int = new Interval ("10-10-1997", "10-20-1997", $OPEN_INT); print "$open_int\n"; # prints (10-10-1997, 10-20-1997) ### check and get overlapping interval ### $i1 = new Interval ("10-30-1997", "12-01-1998"); $i2 = new Interval ("01-20-1996", "11-01-1997"); $i3 = new Interval ("01-01-1995", "04-30-1995"); if ($i1->overlaps ($i2)) { $i4 = $i1->getOverlap($i2); print "$i4\n"; # prints [10-30-1997, 11-01-1997) } if ($i1->overlaps ($i3)){ # tests fails, does not print anything $i5 = $i1->getOverlap($i2); print "$i5\n"; }
All strings which can be used to create a Date::Manip date object can be used to create an Interval. However, the start date must be greater than the stop date. Because Date::Manip both handles dates and times this module can also handle both dates and times. The comparison of intervals is based on the 13 ways intervals can overlap as defined by J.F. Allen (See the litteratur). Further, I have included a small number of interval comparison which are handy if you are only interested in getting the overlapping region of two intervals.
A closed interval is closed in an interval where both the start and the stop values are included in the interval. As an example [10-10-1997, 10-30-1997] both the 10th and the 30th of November is a part of the interval. An open interval is an interval where the start value or the stop value are not included in the interval. In the right open interval [10-10-1997, 10-30-1997) the 10th of November is a part of the interval but the 30th of November is not. There are three types of open intervals - right open intervals, e.g., [10-10-1997, 10-30-1997) - left open intervals, e.g., (10-10-1997, 10-30-1997] - open intervals, e.g., (10-10-1997, 10-30-1997)
An absolute interval is an interval where the start and the stop values of the inteval are anchored on the time line, i.e., they are specific dates as 04-30-1994. A relative interval is an interval where the start or the stop value is not anchored on the time line, e.g., 'tomorrow'. When 'tomorrow' evaluated now it has one value when evaluated a month from now it has a different values. Date::Interval fully supports absolute intervals and to a limited degree relative intervals. The relative intervals supported currently (NOW :-)) are of the following type. $int1 = new Date::Interval("10-21-1997", 'NOBIND NOW'); Relative start and stop values are prefixed with the word 'NOBIND'. In the example 'NOBIND NOW' means that the current time (now) whenever it asked for. So if you ask for the length of $int1 at the 24th of October you get 3 days. If you ask for the length of $int1 again at the 28th of October you get 7 days. I am working on additional support for relative Intervals.
The default interval type is right open intervals. Stick to this interval type if you want to keep life simple. To use Date::Manip the time zone variable must be set. It is default set to Central European Time (CET). For Americans, this is the Capital of Stockholm :-). To change the time zone, e.g., to Eastern Standard Time (EST) put in our script $Date::Manip::TZ = 'EST'; (As an European I assume this must be close to Atlanta, New Mexico). The default input format is default of Date::Manip, that is "10-12-1997" is the 12th of October 1997 not the 10th of December 1997. To change the input format, e.g., put in our script &Date::Manip::Date_Init("DateFormat=non-US"); The default output format is MM-DD-YYY. It Can be changed by calling Interval->setDisplayFormat(<string>). Where <string> is a UnixDate format in Date::Manip. The default separator when an interval is printed is the special variable $, $OUTPUT_FIELD_SEPARATOR. If this value is not defined ',' is used.
The module has a class variable $NOW which contains the current time. The current time must be fixed when relative intervals are compared, otherwise the comparison may return the wrong result. As an example if the two intervals [NOBIND NOW, NOBIND NOW) [NOBIND NOW, NOBIND NOW) are compared for equality the result is true. However, if the equality comparison is implemented by asking four time for the current time the times returned may be different because the *real world clock* ticks between the invocations of getting the current time. If the clock ticks the equality predicate in the example returns false. Because different interval objects must be compared with the same clock the variable must be a class variable and not an instance variable. $NOW is used in the method _to_date.
Tried my best to avoid them send me an email if you are bitten by a bug. Note, the module cannot handle subtract intervals which overlap with "during" overlaps, this results in two intervals (currently results in an empty interval)
- Cannot take references to dates as input parameters for the constructors - Cannot subtract intervals which overlap with "during" overlaps, this results in two intervals (currently results an error message and an empty interval is returned) - Implement getOverlap and overloaded operators for relative intervals
- Made code to fit onto 80 columns - Added POD for each method/function ### Changes version 0.01 => 0.02 ### - Add overload <, >, ==, !=, <=>. - Add stringLength, to print length of interval in a more readable way. - Changed the default separator to the $, special variable - Added support for comparison of relative intervals Changes thanks to Tim Bruce - Changed the module name from Interval to Date::Interval - Added methods getStart and getStop. - Added method lengthString to print nicely the length of the interval. - Changed the default output format to be similar to the default input format - Taken BEGIN {$Date::Manip::TZ = "CET"; &Date_Init ("DateFormat=non-US");} out because it is anti-social :-) - Added to POD that the both dates and times can be used with intervals - Added to POD the description of open and closed intervals
Allen, J. F., "An Interval-Based Representation of Temporal Knowledge", Communication of the ACM, 26(11) pp. 832-843, November 1983.
Kristian Torp <torp@cs.auc.dk>
1 POD Error
The following errors were encountered while parsing the POD:
Non-ASCII character seen before =encoding in 'Allen´s'. Assuming CP1252
To install Date::Interval, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Date::Interval
CPAN shell
perl -MCPAN -e shell install Date::Interval
For more information on module installation, please visit the detailed CPAN module installation guide.