The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Date::Gregorian - Gregorian calendar

SYNOPSIS

  use Date::Gregorian;
  use Date::Gregorian qw(:weekdays :months);

  $date = Date::Gregorian->new->set_ymd(1999, 12, 31);
  $date2 = $date->new;

  if ($date->check_ymd($year, $month, $day)) {
    # valid, $date has new value
  }
  else {
    # not valid, $date remains unchanged
  }

  ($year, $month, $day) = $date->get_ymd;

  $wd = (qw(Mon Tue Wed Thu Fri Sat Sun))[$date->get_weekday];
  $date->set_yd(2000, 366);           # Dec 31, 2000
  ($year, $day_in_year) = $date->get_yd;
  $date->set_ywd(1998, 53, 6);        # Sun Jan 3, 1999
  ($year, $week_in_year, $weekday) = $date->get_ywd;

  if ($date->check_ywd($year, $week, $weekday)) {
    # valid, $date has new value
  }
  else {
    # not valid, $date remains unchanged
  }

  $date->add_days(-100);
  $delta = $date->get_days_since($date2);
  $date->set_easter($y);
  $date->set_today;
  $date->set_localtime($time);
  $date->set_gmtime($time);
  $time = $date->get_gmtime;

  $date->configure(1752, 9, 14);
  $date->configure(1752, 9, 14, 1753);        # United Kingdom
  $date2->configure(1918, 2, 14);             # Russia

  $date2->set_ymd(1917, 10, 25);      # pre-Gregorian Oct 25, 1917
  $date->set_date($date2);            # Gregorian Nov 7, 1917 (same day)

  if ($date->is_gregorian) {
    # date is past configured calendar reformation,
    # thus in Gregorian notation
  }
  else {
    # date is before configured calendar reformation,
    # thus in Julian notation
  }

  # get the first sunday in October:
  $date->set_ymd($year, 10,  1)->set_weekday(6, '>=');
  # get the last sunday in October:
  $date->set_ymd($year, 11,  1)->set_weekday(6, '<');

  # calculate number of days in 2000:
  $days = $date->get_days_in_year(2000);

DESCRIPTION

Calendars define some notation to identify days in history. The Gregorian calendar, now in wide use, was established by Pope Gregory XIII in AD 1582 as an improvement over the less accurate Julian calendar that had been in use before. Both of these calendars also determine certain holidays. Unfortunately, the new one was not adopted everywhere at the same time. Thus, the correct date for a given historic event can depend on its location. Astronomers usually expand the official Julian/Gregorian calendar backwards beyond AD 1 using zero and negative numbers, so that year 0 is 1 BC, year -1 is 2 BC, etc.

This module provides an object class representing days in history. You can get earlier or later dates by way of adding days to them, determine the difference in days between two of them, and read out the day, month and year number as the (astronomic) Gregorian calendar defines them (numbers 1 through 12 representing January through December). Moreover, you can find out weekdays, easter sundays, week in year and day in year numbers.

For convenience, it is also possible to define the switching day from Julian to Gregorian dates and the switching year from pre-Gregorian to Gregorian easter schedule. Use configure with the first valid date of the new calendar and optionally the first year the new easter schedule was used (default 1583).

The module is based on an algorithm devised by C. F. Gauss (1777-1855). It is completely written in Perl for maximum portability.

All methods except get_* return their object. This allows for shortcuts like:

  $pentecost = Date::Gregorian->new->set_easter(2000)->add_days(49);

Numbers 0 through 6 represent weekdays Monday through Sunday. Day in month ranges from 1 to 31, day in year from 1 to 366, week in year from 1 to 53. Weeks are supposed to start on Monday. The first week of a year is the one containing January 4th. These definitions are slightly closer to ISO 8601 than to Perl's builtin time conversion functions. Weekday numbers, however, are zero-based for ease of use as array indices.

Numeric parameters must be integer numbers throughout the module.

For convenience, weekdays and months can be imported as constants MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY, and JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER. The tag :weekdays provides all weekdays, as :months does all month names. By default, nothing is exported.

new creates a Date::Gregorian object from scratch (if called as a class method) or as a copy of an existing object. The latter is more efficient than the former.

set_ymd sets year, month and day to new absolute values. Days and months out of range are silently folded to standard dates, in a way that is intended to preserve continuity: Month 13 is treated as month 1 of the next year, month 14 as month 2 of the next year, month 0 as month 12 of the previous year, day 0 as the last day of the previous month, etc. Thus, e.g., the date 10000 days before February 22, 2002 can be defined like this:

  $date->set_ymd(2002, 2, 22-10000)

check_ymd, on the other hand, checks a given combination of year, month and day for validity. Given a valid date, the object is updated and the object itself is returned, evaluating to true in boolean context. Otherwise, the object remains untouched and undef is returned.

get_ymd returns year, month and day as a three-item list.

get_weekday returns the weekday as a number in the range of 0 to 6, with 0 representing Monday, 1 Tuesday, 2 Wednesday, 3 Thursday, 4 Friday, 5 Saturday and 6 representing Sunday.

set_yd and get_yd set or get dates as a pair of year and day in year numbers, day 1 representing January 1, day 32 February 1 etc.

set_ywd and get_ywd set or get dates as a tuple of year, week in year and day in week numbers. As noted above, weeks are supposed to start on Mondays. Weeks containing days of both December and January belong to the year containing more days of them. Because of this, get_ywd and get_ymd may return different year numbers. Week numbers range from 1 to 53 (max).

check_ywd checks a given combination of year, week in year and weekday for validity. Given a valid date, the object is updated and the object itself is returned, evaluating to true in boolean context. Otherwise, the object remains untouched and undef is returned.

Note that year 1582 (or whatever year was configured to have the Gregorian calendar reformation) was considerably shorter than a normal year. Such a year has some invalid dates that otherwise might seem utterly inconspicuos.

add_days increases, or, given a negative argument, decreases, a date by a number of days. Its new value represents a day that many days later in history if a positive number of days was added. Adding a negative number of days consequently shifts a date back towards the past.

get_days_since computes the difference of two dates as a number of days. The result is positive if the given date is an earlier date than the one whose method is called, negative if it is a later one. Look at it as a subtraction operation, yielding a positive result if something smaller is subtracted from something larger, "smaller" meaning "earlier" in this context.

set_easter computes the date of Easter sunday of a given year, taking into account how the date object was configured.

configure defines the way the Gregorian calendar reformation should be handled in calculations with the date object and any new ones later cloned with new from this one. The first three arguments specify the year, month and day of the first day the new calendar was in use. The optional fourth argument defines the first year the new easter schedule has to be used in easter calculations. Re-configuring a date object is legal and does not change the day in history it represents while possibly changing the year, month and day values related to it.

is_gregorian tells whether a date is past the configured calendar reformation and thus will yield year, month and day values in Gregorian mode.

set_weekday computes a date matching a given weekday that is close to the date it is applied to. The optional relation parameter may be one of '>=', '>', '<=' or '<', and determines if the resulting date should be "equal or later", later, "equal or earlier", or earlier, respectively, than the initial date. Default is '>='.

set_today computes a date value equivalent to the current date in the current locale. Local time is assumed to run in Gregorian mode.

set_localtime likewise computes a date value equivalent to a given time value in the current locale.

set_gmtime computes a date value equivalent to a given Unix timestamp in the GMT locale.

get_gmtime converts a date value back to a Unix timestamp in the GMT locale. Undef is returned if the date seems to be out of range. Note that the precision of timestamps represented by date objects is normally limited to days. Thus converting a timestamp to a date and back again usually truncates the timestamp to midnight. Extension classes may behave differently, however.

Note that Date::Gregorian does not define a get_localtime method for lack of a simple way to deal with daylight saving time changes, leap seconds and other peculiarities of local timezones.

get_days_in_year computes the number of days in a given year (independent of the year stored in the date object).

AUTHOR

Martin Hasch <hasch-cpan-dg@cozap.com>, November 1999.

CAVEATS

Does not work with non-integer values.

SEE ALSO

The sci.astro Calendar FAQ, Date::Calc, Date::Gregorian::Business, DateTime.