NAME

Date::Interval - handling of temporal intervals based on Date::Manip

COPYRIGHT

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.

Class Methods

setDefaultIntervalType

Description: Sets the default <interval type>
Input:       <interval type>
Output:      none

getDefaultIntervalType

Description: Gets the default <interval type>
Input:       none
Output:      <interval type>

setDisplayFormat

Description: Sets the default <display format>
Input:       <display format>
Output:      none

getDisplayFormat

Description: Gets the default <display format>
Input:       none
Output:      <display format>

Public Methods

new

Description: Constructor
Input:       <start value> <stop value> [<interval type>]
Output:      reference   

length

Description: Returns the Length of an interval in Date::Manip format
Input:       none
Output:      <delta>

length

Description: Returns the length of an interval in string format
Input:       none
Output:      string

get

Description: Returns the interval in string format
Input:       none
Output:      string

getStart

Description: Returns the <start value>
Input:       none
Output:      <date>

getStop

Description: Returns the <stop value>
Input:       none
Output:      <date>

overlaps

Description: Checks if two intervals overlap
Input:       <interval>
Output:      <boolean>

getOverlap

Description: Return the overlap of two intervals
Input:       <interval>
Output:      <interval> | undef

before

Description: Examines if interval is before
Input:       <interval>
Output:      <boolean>

meets

Description: Examines if intervals meets
Input:       <interval>
Output:      <boolean>

leftOverlaps

Description: Examines if two intervals left overlap
Input:       <interval>
Output:      <boolean>

rightOverlaps

Description: Examines if two intervals right overlap
Input:       <interval>
Output:      <boolean>

during

Description: Examines if two intervals during overlap
Input:       <interval>
Output:      <boolean>

totallyOverlaps

Description: Examines if two intervals totally overlap
Input:       <interval>
Output:      <boolean>

extends

Description: Examines if two intervals extends
Input:       <interval>
Output:      <boolean>

after

Description: Examines if two intervals after
Input:       <interval>
Output:      <boolean>

howOverlaps

Description: Describes in text how intervals overlaps
Input:       <interval>
Output:      to screen

AllenHowOverlaps

Description: Return how intervals overlap in Allen´s terminology
Input:       <interval>
Output:      to screen

AllenBefore

Description: Examines if intervals Allen before
Input:       <interval>
Output:      <boolean>

AllenMeets

Description: Examines if intervals Allen meets
Input:       <interval>
Output:      <boolean>

AllenLeftOverlaps

Description: Examines if intervals Allen left overlaps
Input:       <interval>
Output:      <boolean>

AllenLeftCovers

Description: Examines if intervals Allen left covers
Input:       <interval>
Output:      <boolean>

AllenCovers

Description: Examines if intervals Allen covers
Input:       <interval>
Output:      <boolean>

AllenStarts

Description: Examines if intervals Allen starts
Input:       <interval>
Output:      <boolean>

AllenEquals

Description: Examines if intervals Allen equals
Input:       <interval>
Output:      <boolean>

AllenRightCovers

Description: Examines if intervals Allen right covers
Input:       <interval>
Output:      <boolean>

AllenDuring

Description: Examines if intervals Allen during
Input:       <interval>
Output:      <boolean>

AllenFinishes

Description: Examines if intervals Allen finishes
Input:       <interval>
Output:      <boolean>

AllenRightOverlaps

Description: Examines if intervals Allen right overlaps
Input:       <interval>
Output:      <boolean>

AllenExtends

Description: Examines if intervals Allen extends
Input:       <interval>
Output:      <boolean>

AllenAfter

Description: Examines if intervals Allen after
Input:       <interval>
Output:      <boolean>

Private Methods

_initialize

Description: Initization of new instances
Input:       <start value> <stop value> [<interval type>]
Output:      none

_new_empty

Description: Initization of new empty instance
Input:       none
Output:      empty <interval>

_setIntervalType

Description: Sets the <interval type>
Input:       <interval type>
Output:      <boolean>

_setBrackets

Description: Sets the interval brackets
Input:       <interval end> <interval end>
Output:      <boolean>

_overlaps

Description: Examines how intervals overlaps
Input:       <interval>
Output:      <overlap type> || FALSE

_AllenOverlaps

Description: Finds how intervals overlap in Allen terminology
Input:       <interval>
Output:      <Allen overlap type>

Overloaded Operators

_plus

Description: + operator. If two intervals overlaps the union is returned
Input:       <interval> <interval>
Output:      <interval> || undefined

_minus

Description: - operator. 
             If two intervals overlaps the intersection is returned
Input:       <interval> <interval>
Output:      <interval> [ <interval> ] || undefined

_smaller_than

Description: < operator. 
Input:       <interval> <interval>
Output:      <boolean>

_greater_than

Description: > operator. 
Input:       <interval> <interval>
Output:      <boolean>

_equal

Description: == operator. 
Input:       <interval> <interval>
Output:      <boolean>

_equal

Description: != operator. 
Input:       <interval> <interval>
Output:      <boolean>

_spaceship

Description: <=> operator. 
             Use ONLY for sorting because based on the start value
Input:       <interval> <interval>
Output:      -1 || 0 || 1    

_stringify

Description: For strinifying an interval
Input:       <interval>
Output:      string

_getEndPoint

Description: Converts a string to an <end point>
Input:       string
Output:      <end point> <value type>

_to_date

  Description: Converts <end point> to a date
  Input:       <fix clock> <value type> <end point> [<start date value type> 
						     <start date>]
  Output:      <date>

_getCurrentTime

Description: Converts an <end point> to a string
Input:       <boolean>
Output:      string

_to_string

Description: Converts an <end point> to a string
Input:       <value type> <end point>
Output:      string

SYNOPSIS

    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";
    }

DESCRIPTION

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.

Open and Closed 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)

Absolute and Relative Intervals

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.

Defaults

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 "Fixed" Clock

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.

"Non-terminals" used in the Source Code

<delta> ::= Date::Manip delta data type
<date> ::= Date::Manip data type
<interval end> ::= CLOSE || OPEN
<interval type> ::= CLOSED_INT || OPEN_INT || LEFT_OPEN_INT || RIGHT_OPEN_INT
<value type> ::= ABSOLUTE || RELATIVE
<overlap type> ::= How two intervals overlaps
<Allen overlap type> ::= How two intervals Allen overlaps

BUGS

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)

TODO

- 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

Change History ### Changes version 0.02 => 0.03 ### - TODO: during overlap

- 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

LITTERATURE

Allen, J. F., "An Interval-Based Representation of Temporal Knowledge",
Communication of the ACM, 26(11) pp. 832-843, November 1983.

AUTHORS

Kristian Torp <torp@cs.auc.dk>

1 POD Error

The following errors were encountered while parsing the POD:

Around line 630:

Non-ASCII character seen before =encoding in 'Allen´s'. Assuming CP1252