Author image Tom Wyant
and 4 contributors


DateTime::Calendar::Christian - Dates in the Christian calendar


  use DateTime::Calendar::Christian;

  $dt = DateTime::Calendar::Christian->new( year  => 1752,
                                            month => 10,
                                            day   => 4,
                                            reform_date => $datetime );


DateTime::Calendar::Christian is the implementation of the combined Julian and Gregorian calendar.

See DateTime for information about most of the methods.


The Julian calendar, introduced in Roman times, had an average year length of 365.25 days, about 0.03 days more than the correct number. When this difference had accumulated to about ten days, the calendar was reformed by pope Gregory XIII, who introduced a new leap year rule. To correct for the error that had built up over the centuries, ten days were skipped in October 1582. In most countries, the change date was later than that; England went Gregorian in 1752, and Russia didn't change over until 1918.


This manpage only describes those methods that differ from those of DateTime. See DateTime for all other methods. A spirited attempt has been made to implement the entire DateTime interface.

Methods not documented below may behave in unexpected ways when they involve dates both before and after the reform date. For example, week_number(), when called on a date in the reform year but after the reform, returns the week number in the Gregorian year, not the actual year.

Caveat programmer.

  • new( ... )

    Besides the usual parameters ("year", "month", "day", "hour", "minute", "second", "nanosecond", "locale", "formatter" and "time_zone"), this class method takes the additional "reform_date" parameter. See SPECIFYING REFORM DATE below for how to specify this.

    If this method is used as an instance method and no "reform_date" is given, the "reform_date" of the returned object is the same as the one of the object used to call this constructor. This means you can make "date generators", that implement a calendar with a fixed reform date:

      $english_calendar = DateTime::Calendar::Christian(
                              reform_date => DateTime->new( year  => 1752,
                                                            month => 9,
                                                            day   => 14 )

    or equivalently:

      $english_calendar = DateTime::Calendar::Christian(
                              reform_date => 'UK' );

    You can use this generator to create dates with the given reform_date:

      $born = $english_calendar->new( year => 1732, month => 2, day => 22 );
      $died = $english_calendar->new( year => 1799, month => 12, day => 14 );

    When a date is given that was skipped during a calendar reform, it is assumed that it is a Gregorian date, which is then converted to the corresponding Julian date. This behaviour may change in future versions. If a date is given that can be both Julian and Gregorian, it will be considered Julian. This is a bug.

  • from_epoch, from_object, from_day_of_year, last_day_of_month

    These methods accept an additional "reform_date" argument. Note that the epoch is defined for most (all?) systems as a date in the Gregorian calendar. But this module will still represent it as a Julian date if the epoch gives a date before the reform date.

  • reform_date

    Returns the date of the calendar reform, as a DateTime object.

  • is_julian, is_gregorian

    Return true or false indicating whether the datetime object is in a specific calendar.

  • calendar_name

    Return 'Julian' or 'Gregorian', depending on the value returned by is_julian().

  • is_leap_year

    This method returns a true or false indicating whether or not the datetime object is in a leap year. If the object is in the year of the date reform, this method indicates whether there is a leap day in that year, irrespective of whether the datetime object is in the same calendar as the possible leap day.

  • days_in_year

    Returns the number of days in the year. Is equal to 365 or 366, except for the year(s) of the calendar reform.

  • day_of_year, day_of_year_0

    Returns the day of the year, either one-based or zero-based depending on the actual method called. In the reform year this is the actual number of days from January 1 (Julian) to the current date, whether Julian or Gregorian.

  • add, subtract

    These are done in terms of duration, so that, for example, subtracting a day from the reform date (Gregorian) gets you the day before the reform date (Julian).

    When months and/or years are involved, the result is modified from a straight rata die calculation to add or subtract the number of days skipped by the reform. Without this modification, George Washington's birthday of February 11 Julian would drift forward in the Gregorian calendar as the difference between the two calendars increased. With this modification, it is February 22 Gregorian regardless of the actual days difference between the two calendars.

    Note that in versions 0.12 and earlier this modification was applied to all durations. This produced anomalous (i.e. wrong) results when adding or subtracting large numbers of days.

    Beginning with version 0.12_01 the modification is only applied to months (and years, since years are folded into months when a DateTime::Duration object is created.) The actual order of operation is that specified by DateTime: the days component of the duration is applied first, then months (with the above modification), then minutes, seconds, and nanoseconds. This can give rise to commutation/round-trip failures, and these may be more common under this change, but this appears to be the price of fixing the bug described in the previous paragraph.

    The DateTime documentation notes that this can happen in that module even in simple cases, such as adding a month to (say) January 31. It also notes that if order of operation is an issue, you can force it by doing something like

     $dt->add( months => 3 )->add( days => 5 );

    to force months to be done first.

  • strftime

    This override allows selected methods of this class (i.e. not inherited from DateTime) to be used in the '%{method_name}' construction in templates. The only method allowed at the moment is calendar_name.

  • gregorian_deviation( [$datetime] )

    This method returns the difference in days between the Gregorian and the Julian calendar. If the parameter $datetime is given, it will be used to calculate the result; in this case this method can be used as a class method.

    This deviation increments on March 1 (Julian) of any year which is a leap year in the Julian calendar but not the Gregorian calendar.

  • julian_deviation( [$datetime] )

    This method was added in version 0.13.

    This method returns the difference in days between the Gregorian and the Julian calendar. If the parameter $datetime is given, it will be used to calculate the result; in this case this method can be used as a class method.

    This deviation increments on March 1 (Gregorian) of any year which is a leap year in the Julian calendar but not the Gregorian calendar.

  • DefaultReformDate

    This static method returns a DateTime object representing the default reform date. If called with an argument, the argument becomes the new reform date, which is returned. The argument is either a DateTime object (or something that can be converted into one) or a reform date location name. See SPECIFYING REFORM DATE below for what kind of arguments can be specified.


This module implements the following interfaces:

  • Storable

    This module implements the Storable interface. All the donkey work is done by DateTIme.

  • Overloading

    Addition, subtraction, and both string and numeric comparison are overloaded. Objects with no date (that is, objects initialized as "date generators") collate before objects with a date.


The reform date represents the first date the Gregorian calendar came into use. It can be specified a number of different ways:

  • A DateTime object, or an object that can be converted into one.

  • A location name (case-insensitive) from the following list:

     Italy -------------- 1582-10-15 # and some other Catholic countries
     France ------------- 1582-12-20
     Belgium ------------ 1583-1-1
     Holland ------------ 1583-1-1   # or 1583-1-12?
     Liege -------------- 1583-2-21
     Augsburg ----------- 1583-2-24
     Treves ------------- 1583-10-15
     Bavaria ------------ 1583-10-16
     Tyrolia ------------ 1583-10-16
     Julich ------------- 1583-11-13
     Cologne ------------ 1583-11-14 # or 1583-11-13?
     Wurzburg ----------- 1583-11-15
     Mainz -------------- 1583-11-22
     Strasbourg_Diocese - 1583-11-27
     Baden -------------- 1583-11-27
     Carynthia ---------- 1583-12-25
     Bohemia ------------ 1584-1-17
     Lucerne ------------ 1584-1-22
     Silesia ------------ 1584-1-23
     Westphalia --------- 1584-7-12
     Paderborn ---------- 1585-6-27
     Hungary ------------ 1587-11-1
     Transylvania ------- 1590-12-25
     Prussia ------------ 1610-9-2
     Hildesheim --------- 1631-3-26
     Minden ------------- 1668-2-12
     Strasbourg --------- 1682-2-16
     Denmark ------------ 1700-3-1
     Germany_Protestant - 1700-3-1
     Gelderland --------- 1700-7-12
     Faeror ------------- 1700-11-28 # or 1700-11-27?
     Iceland ------------ 1700-11-28
     Utrecht ------------ 1700-12-12
     Zurich ------------- 1701-1-12
     Friesland ---------- 1701-1-12  # or 1701-01-13?
     Drente ------------- 1701-5-12  # or 1701-01-12?
     UK ----------------- 1752-9-14
     Bulgaria ----------- 1915-11-14 # or 1916-04-14?
     Russia ------------- 1918-2-14
     Latvia ------------- 1918-2-15
     Romania ------------ 1919-4-14  # or 1924-10-14?
  • An array reference.

    The first seven elements of the array are year, month, day, hour, minute, second and nanosecond. Element [0] is the only one that is required. Elements [1] and [2] default to 1, and the rest to 0.

  • An ISO-8601-ish string.

    The string is split on non-numerics, and the reform date initialized from a reference to the resultant array, as described in the previous item. The string must be the punctuated form; that is, '1752-9-14' will work, but '17520914' will not. There must not be a zone specification, and the year must not be signed.


  • There are problems with calendars switch to Gregorian before 200 AD or after about 4000 AD. Before 200 AD, this switch leads to duplication of dates. After about 4000 AD, there could be entire missing months. (The module can handle dates before 200 AD or after 4000 AD just fine; it's just the calendar reform dates that should be inside these limits.)

  • There may be functions that give the wrong results for the year of the calendar reform. The function truncate() is a known problem, and today() may be a problem. If you find any more problems, please let me know.


Support for this module is provided via the email list. See for more details.

Please report bugs to,, or in electronic mail to


Eugene van der Pijll <>

Thomas R. Wyant, III wyant at cpan dot org


Copyright (c) 2003 Eugene van der Pijll. All rights reserved.

Copyright (C) 2016-2022 Thomas R. Wyant, III

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself; either the GNU General Public License version 1 (or, at your option, any later version) or the Artistic License. For more details, see the full text of the licenses in the directory LICENSES.

This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.


DateTime, DateTime::Calendar::Julian mailing list