Date-Manip

 view release on metacpan or  search on metacpan

lib/Date/Manip/Date.pod  view on Meta::CPAN

# Copyright (c) 1995-2026 Sullivan Beck. All rights reserved.
# This program is free software; you can redistribute it and/or modify it
# under the same terms as Perl itself.

=pod

=head1 NAME

Date::Manip::Date - Methods for working with dates

=head1 SYNOPSIS

   use Date::Manip::Date;
   $date = new Date::Manip::Date;

=head1 DESCRIPTION

This module works specifically with date objects.

Although the word date is used extensively here, it is actually
somewhat misleading.  Date::Manip works with the full calendar date
(year, month, day, and week when appropriate), time of day (hour,
minute, second), and time zone.  It doesn't work with fractional
seconds.

=head1 METHODS

=over 4

=item B<base>

=item B<config>

=item B<err>

=item B<is_date>

=item B<is_delta>

=item B<is_recur>

=item B<new>

=item B<new_config>

=item B<new_date>

=item B<new_delta>

=item B<new_recur>

=item B<tz>

Please refer to the Date::Manip::Obj documentation for these methods.

=item B<calc>

   $date2 = $date->calc($delta [,$subtract]);
   $delta = $date->calc($date2 [,$subtract] [,$mode]);

Please refer to the Date::Manip::Calc documentation for details.

=item B<cmp>

   $val = $date1->cmp($date2);

This compares two different dates (both of which must be valid date
objects). It returns -1, 0, or 1 similar to the cmp or <=> operators
in perl. The comparison will automatically handle time zone differences
between the two dates (i.e. they will be sorted in order as they
appear in the GMT zone).

A warning is printed if either of the date objects does not include
a valid date.

=item B<complete>

   $flag = $date->complete([$field]);

This tests the date stored in the object to see if it is complete or
truncated (see below for a discussion of this).

lib/Date/Manip/Date.pod  view on Meta::CPAN

in time 1 day at a time until a work day is found.  If $tomorrowfirst
is non-zero (or if it is omitted and the config variable TomorrowFirst
is non-zero), we look to the future first.  Otherwise, we look in the
past first.  In other words, in a normal week, if $date is Wednesday,
$date is returned.  If $date is Saturday, Friday is returned.  If
$date is Sunday, Monday is returned.  If Wednesday is a holiday,
Thursday is returned if $tomorrowfirst is non-nil or Tuesday
otherwise.

=item B<next_business_day>

=item B<prev_business_day>

   $date->next_business_day($off [,$checktime]);
   $date->prev_business_day($off [,$checktime]);

The next_business_day method sets the given date to $off (which can be
a positive integer or zero) business days in the future. The prev_business_day
method sets the date to $off business days in the past.

First, $date is tested. If $checktime is nonzero, the date must fall
on a business date, and during business hours. If $checktime is zero,
the time check is not done, and the date must simply fall on a
business date.

If the check fails, the date is moved to the start of the next
business day (if $checktime is nonzero) or the next business day at
the current time (if $checktime is zero). Otherwise, it is left
unmodified.

Next, if $off is greater than 0, the day $off work days from now is
determined.

One thing to note for the prev_business_day method is that if $date
check fails, the date is set to the next business date, exactly like
next_business_day. In other words, if $date is not a business day, the
call:

   $date->prev_business_day(0 [,$checktime]);

moves $date forward in time instead of backward which is nonintuitive,
but you just have to think of day 0 as being the next business day if
$date is not a business day.

As a result, the following two calls ALWAYS give the same result:

   $date->next_business_day(0 [,$checktime]);
   $date->prev_business_day(0 [,$checktime]);

no matter what date is stored in $date.

=item B<parse>

   $err = $date->parse($string [,@opts]);

This parses a string which should include a valid date and stores
it in the object. If the string does not include a valid date, an
error is returned. Use the err method to see the full error
message.

A full date may include a calendar date (year, month, day), a time of
day (hour, minute, second), and time zone information. All of this can
be entered in many different formats.

For information on valid date formats, refer to the section VALID
DATE FORMATS. For information on valid time zone information, refer
to the section VALID TIME ZONE FORMATS.

If no time zone information is included in the date, it is treated
as being in the local time zone.

If time zone information is included, the date will be kept in that
time zone, and all operations will be done in that time zone.  The
convert method can be used to change the time zone to the local time
zone, or to another time zone.

Some things to note:

All strings are case insensitive.  "December" and "DEceMBer" are
equivalent.

When a part of the date is not given, defaults are used. This is
described below in the section "Complete vs. truncated dates and times".

The year may be entered as 2 or 4 digits.  If entered as 2 digits, it will
be converted to a 4 digit year.  There are several ways to do this based on
the value of the YYtoYYYY config variable.  Refer to the Date::Manip::Config
documentation for more details.

Dates are always checked to make sure they are valid.

If any other arguments are passed in, they act as options which may
improve the speed of parsing. These include:

   noiso8601  Do not try to parse the
              date as an ISO 8601 date
              or time.
   nodow      Do not try to parse a
              day-of-week (Monday) in
              the string.
   nocommon   Do not try to parse the
              date using the formats
              in the "Common date
              formats" section.
   noother    Do not try to parse the
              date using the "Less common
              date formats" or a time
              using the "Other time
              formats".
   nospecial  Do not try to parse the
              date using the "Special
              date strings" formats
              or a time using the
              "Special time strings"
              formats, or as a
              combined date/time using
              the "Additional combined
              date and time" formats.
   nodelta    Do not treat deltas as
              a date relative to now.
   noholidays Do not parse holiday

lib/Date/Manip/Date.pod  view on Meta::CPAN


These return the value of the date stored in the object.

In scalar context, a printable string in the form YYYYMMDDHH:MN:SS
is returned. In list context, a list is returned of (Y,M,D,H,MN,S).

If $type is omitted, the date is returned in the time zone it was
parsed in.

If $type is "local", it is returned in the local time zone (which
is either the system time zone, or the zone specified with the
SetDate or ForceDate config variables).

If $type is "gmt", the date is returned in the GMT time zone.

An empty string or list is returned in the case of an error (and
an error code is set).

=item B<week_of_year>

   $wkno = $date->week_of_year([$first]);

This figures out the week number for the date stored in $date.  It uses
the config variables FirstDay and Week1ofYear to determine this.  For
historical reasons, an argument $first may be passed in.  It must be
between 1 and 7 and refers to the first day of the week and overrides
whatever the FirstDay variable is set to.

NOTE: This routine should only be called in rare cases.  Use printf
with the %W, %U, %J, %L formats instead as that will always return the
correct values for week and year.

This routine returns a week between 0 and 53 which must then be
"fixed" to get into the ISO 8601 weeks from 1 to 53.  A date which
returns a week of 0 actually belongs to the last week of the previous
year.  A date which returns a week of 53 may belong to the first week
of the next year.

=back

=head1 ISSUES WITH PARSING DATES

The following issues may occur when parsing dates that should be
understood to make full use of this module.

=over 4

=item B<Complete vs. truncated dates and times>

Date formats are either complete or truncated. A complete date fully
specifies the year, month, and day and a complete time fully specifies
the hour, minute, and second.

It should be understood that in many instances, the information may be
implied rather than explicitly stated, but it is still treated as
complete.

For example, the date "January 3" is complete because it implies the
current year.

A truncated calendar date or time does not include information about
some of the fields. Date::Manip will never work with a partial date or
time, so defaults will be supplied.

For example, the date "2009-01" is missing a day field, so a default
will be used. In this case, the day will be the 1st, so this is
equivalent to "Jan 1st 2009". If only the year is given, it will
default to Jan 1.

If the time, or any of it's components is missing, they default to
00. So the time "12:30" and "12:30:00" are equivalent.

The "complete" method can be used to check what type of date was
parsed, and which values were specified (either explicitly or implied)
and which were provided as a default. It should be noted that there
is no way to differentiate between an explicit and implied value.

A string with a date and/or time may consist of any of the following:

   a complete date and a time (complete or truncated)
   a truncated date with no time
   a time (complete or truncated) with no date

In other words, the date "Jan 2009 12:30" is not valid since it consists
of a time with a truncated date.

=back

=head1 VALID TIME ZONE FORMATS

When specifying a time zone, it can be done in three different ways.
One way is to specify the actual time zone. The second is to supply
a valid time zone abbreviation. The third is to specify an offset (with
an optional abbreviation). The following dates illustrate the these
formats.

The timezone information always follows the time immediately, and may
only be included if a time is included. The following examples use
an ISO 8601 format for the date/time, but any of the other date and
time formats may be used.

The first way to specify the time zone is to specify it by complete name
(or using one of the standard aliases):

   2001-07-01-00:00:00 America/New_York

Although this is unambiguous when it comes to determining the time zone,
the time is ambiguous in most zones for one hour of the year. When
a time change occurs during which the clock is moved back, the same
wall clock time occurs twice.

For example, in America/New_York, on Sunday, Nov 2, 2008, at 02:00 in
the morning, the clock was set back to 01:00. As a result, the date
Nov 2, 2008 at 01:30 is ambiguous. It is impossible to determine if
this refers to the 01:30 that occurred half an hour before the time
change, or the one 30 minute after the change.

In practice, if this form is used, the date will be assigned to
standard time, meaning that there will be some times (typically 1 hour
per year) which cannot be expressed this way. As such, this method is
discouraged.

lib/Date/Manip/Date.pod  view on Meta::CPAN

Date::Manip::Zones documentation, and the first match (i.e. the one in
which the given date/time and abbreviation are valid) determines the
time zone which will be used. A great deal of effort has been made to
ensure that the most likely time zone will be obtained (i.e. the most
common time zones are tested before less common ones), so in most
cases, the desired results will be obtained.

If the default order does not yield the desired time zone, the order of
testing can be modified using the abbrev method described in the
Date::Manip::TZ documentation.

Although the time zone is ambiguous, the date is not, since only
time zones for which the date are valid will be used.

The third way to specify the time zone is by specifying an offset and
an optional abbreviation:

   2001-07-01-00:00:00 -04
   2001-07-01-00:00:00 -0400
   2001-07-01-00:00:00 -040000
   2001-07-01-00:00:00 -04:00
   2001-07-01-00:00:00 -04:00:00

   2001-07-01-00:00:00 -04 (EDT)
   2001-07-01-00:00:00 -0400 (EDT)
   2001-07-01-00:00:00 -040000 (EDT)
   2001-07-01-00:00:00 -04:00 (EDT)
   2001-07-01-00:00:00 -04:00:00 (EDT)

   2001-07-01-00:00:00 -04 EDT
   2001-07-01-00:00:00 -0400 EDT
   2001-07-01-00:00:00 -040000 EDT
   2001-07-01-00:00:00 -04:00 EDT
   2001-07-01-00:00:00 -04:00:00 EDT

As with the abbreviation, the offset is almost never sufficient to
uniquely determine the time zone (and it is not even guaranteed that
both the offset and abbreviation will, though in practice, it is
probably sufficient). In this instance, the time zone will be
determined by testing all time zones which have the given offset (and
abbreviation if it is included) until one is found which matches the
pieces of information supplied. For more information about how this
testing is done, refer to the def_zone method of the Date::Manip::TZ
documentation.

=head1 VALID DATE FORMATS

There are several categories of date formats supported by Date::Manip.
These are strings which specify only the year/month/day fields.

These formats explicitly set the date, but not the time. These formats
may be combined with a time string (as specified below) to set both
the date and time. If this is not done, the default time is determined
by the DefaultTime config variable.

=over 4

=item B<ISO 8601 dates>

The preferred date formats are those specified by ISO 8601. The
specification includes valid calendar date and valid time formats.
Date::Manip will handle all of these formats, but does not require
that the dates rigidly adhere to the specification since the ultimate
goal of Date::Manip is to handle dates as they are represented in
real life and some common variations exist which are similar to, but
not identical to, those from the specification.

A calendar date includes the following fields:

   CC    2-digit representation of the century
   YY    2-digit representation of the year in
         a century
   MM    2-digit representation of a month
   DD    2-digit representation of a day of month
   DoY   3-digit representation of a day of year
         (001-366)
   Www   the character "W" followed by a 2-digit
         week of the year (01-53)
   D     the day of the week (1-7)

The following date formats are considered complete by Date::Manip. In
the following, the date Thu Mar 5 2009 is used as an example.  This is
the 64th day of the year. Thu is the 4th day of the week.  The week
starting Mon, Mar 2 is the 10th week of the year (according the the
ISO 8601 definition). Obviously, some of the formats are only valid
when used at some times. For example, the format --MMDD refers to a
month and day in the current year, so the date Mar 5, 2009 can only be
specified using this format during 2009.

   Format      Notes   Examples

   CCYYMMDD            20090305
   CCYY-MM-DD          2009-03-05

   YYMMDD      1,2,4   090305
   YY-MM-DD            09-03-05

   -YYMMDD     3,4     -090305
   -YY-MM-DD           -09-03-05

   --MMDD      1       --0305
   --MM-DD             --03-05

   ---DD       1       ---05


   CCYYDoY             2009064
   CCYY-DoY            2009-064

   YYDoY       1,4     09064
   YY-DoY              09-064

   -YYDoY      3,4     -09064
   -YY-DoY             -09-064

   -DoY        1       -064


   CCYYWwwD            2009W104
   CCYY-Www-D          2009-W10-4

   YYWwwD      1,4     09W104
   YY-Www-D            09-W10-4

   -YYWwwD     3,4     -09W104
   -YY-Www-D           -09-W10-4

   -YWwwD      1       -9W104

lib/Date/Manip/Date.pod  view on Meta::CPAN

   -YY         4       -09

   --MM                --03

   CCYYWww             2009W10
   CCYY-Www            2009-W10

   YYWww       4       09W10
   YY-Www              09-W10

   -YYWww      3,4     -09W10
   -YY-Www             -09-W10

   -Www                -W10

Notes:

1  These formats are considered truncated in the standard, but since
   they do include (or imply, using the current date for defaults)
   all of the fields, and since they do not introduce any parsing
   complexities, the standard is relaxed, and they are treated as
   complete.

2  These formats are treated differently than in Date::Manip 5.xx as
   described below.

3  These formats are not defined in the ISO 8601 spec, but
   are added for the sake of completeness since they do not
   add any parsing incompatibilities.

4  Formats where the century is not given are described as a year in
   the current century in the specification. Date::Manip treats this
   more generically using the YYtoYYYY config variable. This will be
   used to determine how to determine the full year.

Date::Manip 5.xx handled ISO 8601 dates in a less rigid fashion, and
deviated from the specification in several formats. As of 6.00, the
specification is followed much more closely so that all of the date
formats included in it should produce valid dates.  This changes, in a
backwards incompatible way, the way a few strings will be interpreted
as dates.

As of 6.00, a two-digit date will be treated as CC. Previously, it
was treated as YY.

A six-digit date will be treated as YYMMDD. Previously, it was treated
as YYYYMM.

Previously, dashes were treated as optional in many cases. According
to the specification, dates may be written in expanded form (with all
dashes present) or abbreviate form (with no dashes). As of 6.00, this
is the behavior, so the formats: YYMMDD and YY-MM-DD are allowed, as
per the specification, but the format YY-MMDD is NOT allowed (though
it was previously).

The Www-D formats require a bit of explanation.  According to the
specification, the date:

   1996-w02-3

refers to the day with an ordinal number of 3 within the calendar week
in the 2nd week of 1996.

In the specification, the days of the week are numbered from 1 to 7
(Monday to Sunday), and the week always begins on Monday, so day 1
(Monday) is always the first day of the week, day 2 (Tuesday) is
always the second day of the week, etc.

In Date::Manip, the constraint that the week must start with Monday is
relaxed, allowing the week to begin with Sunday (a far more common
start of the week in calendars, at least in some parts of the world).

This presents a problem though in that the above date could be
interpreted as Wednesday (day 3) of the 2nd week of 1996, or as the
3rd day of the 2nd week of 1996 (which would normally be Wednesday,
but would be Tuesday if the week begins on Sunday).

As of Date::Manip 6.00, the above date will be interpreted as the 3rd
day of the 2nd week. This is a reversal from Date::Manip 5.xx, but I
believe is what the specification would require. For more information,
refer to the Date::Manip::Changes document.

=item B<Common date formats>

Date::Manip supports a number of common date formats. The following fields
may be included in a date:

  YY    2-digit representation of the year
  YYYY  4-digit representation of the year
  M     1- or 2- digit representation of the month
  MM    2-digit representation of the month
  D     1- or 2- digit representation of the day
  DD    2-digit representation of the day
  mmm   The abbreviated or full month name (i.e. Jan)

The following date formats are supported:

   Format      Notes   Examples

   M/D         1,2,3   3/5
   M/D/YY      1       3/5/09
   M/D/YYYY    1       3/5/2009

   YYYY/M/D            2009/3/5

   mmm/D               Mar/5
   mmm/D/YY            Mar/5/09
   mmm/D/YYYY          Mar/5/2009
   D/mmm               5/Mar
   D/mmm/YY            5/Mar/09
   D/mmm/YYYY          5/Mar/2009
   YYYY/mmm/D          2009/Mar/5

   mmmD                Mar5
   mmmDDYY     4       Mar0509
   mmmDDYYYY           Mar052009
   Dmmm                5Mar
   DmmmYY              5Mar09
   DmmmYYYY            5Mar2009
   YYYYmmmD            2009Mar5

   mmmD YY             Mar5 09
   mmmD YYYY           Mar5 2009
   Dmmm YY             5Mar 09
   Dmmm YYYY           5Mar 2009

   mmm/D YY            Mar/5 09
   mmm/D YYYY          Mar/5 2009
   D/mmm YY            5/Mar 09
   D/mmm YYYY          5/Mar 2009

lib/Date/Manip/Date.pod  view on Meta::CPAN

year.  "22nd Sunday" gives the actual 22nd time Sunday occurs in a
given year, regardless of the definition of a week.

=item B<Special date strings>

Most languages have strings which can be used to specify the date (relative
to today). In English, these include the strings:

   today
   tomorrow
   yesterday

There is also support for the British formats:

   today week
   tomorrow week
   yesterday week

which refer to one week after today/tomorrow/yesterday respectively.

Other languages have similar strings.

=item B<Holidays>

You can parse holiday names as dates (including timezones).  For example:

   Christmas
   Christmas 2010
   Christmas 2010 at noon
   Christmas 2010 at noon PST
   Saturday Christmas 2010 at noon

=back

In all of the formats (except for ISO 8601 formats), the day of week
("Friday") can be entered anywhere in the date and it will be checked
for accuracy.  In other words,

  "Tue Jul 16 1996 13:17:00"

will work but

  "Jul 16 1996 Wednesday 13:17:00"

will not (because Jul 16, 1996 is Tuesday, not Wednesday).

=head1 A NOTE ABOUT FOREIGN LANGUAGE DATES

Although Date::Manip has some support for parsing dates in foreign
languages, it must be noted that the formats supported are largely
based on English equivalents.

There are probably many different dates that are perfectly valid, and
in common usage, in other languages which do not have an equivalent in
the English language, and unfortunately, Date::Manip will probably not
parse these.

You are free to send these to me, and I'll see if there is a way to
add them in, but I do not guarantee anything.  Without having a
full-blown language parser (or at least the portion of the language
that is devoted to calendar and time), most of these formats will
simply not be supportable.

=head1 VALID TIME FORMATS

There are several categories of time formats supported by Date::Manip.
These are strings which specify only the hour/minute/second fields.

=over 4

=item B<ISO 8601 times>

A time may be also be complete or truncated.  Again, Date::Manip
treats some formats as complete even though the specification calls
them truncated.

A time may include the following fields:

   HH    2-digit representation of the hour
   MN    2-digit representation of the minutes
   SS    2-digit representation of the seconds
   H+    1+ digit representation of fractional hours
   M+    1+ digit representation of fractional minutes
   S+    1+ digit representation of fractional seconds

The following time formats are considered complete by Date::Manip. The time
12:30:15 will be expressed in the examples.

   Format      Notes   Examples

   HHMNSS      2       123015

   HH:MN:SS            12:30:15

   HHMNSS,S+           123015,5
   HH:MN:SS,S+         12:30:15,5
                       Fractional seconds are ignored

   HHMN,M+             1230,25
   HH:MN,M+            12:30,25
                       This is 12:30:00 + 0.25 minutes

   HH,H+               12,5
                       This is 12:00:00 + 0.5 hours, so
                       this is equivalent to 12:30:00

   -MNSS       1       -3015
   -MN:SS              -30:15

   --SS        1       --15

   -MNSS,S+    1       -3015,5
   -MN:SS,S+           -30:15,5

   -MN,M+      1       -30,25

   --SS,S+     1       --15,5

   HHMN        3       1230
   HH:MN               12:30



( run in 1.110 second using v1.01-cache-2.11-cpan-d8267643d1d )