Date::Easy::Date - easy date class


This document describes version 0.10 of Date::Easy::Date.


    use Date::Easy::Date ':all';

    # guaranteed to have a time of midnight
    my $d = date("3-Sep-1940");

    # addition and subtraction work in increments of days
    my $tomorrow = today + 1;
    my $last_week = today - 7;
    say "$d was ", today - $d, " days ago";

    my $yr = $d->year;
    my $mo = $d->month;
    my $da = $d->day;
    my $ep = $d->epoch;
    my $qr = $d->quarter;
    my $dw = $d->day_of_week;

    say $d->strftime("%d/%m/%Y");

    my $tp = $d->as('Time::Piece');


A Date::Easy::Date object is really just a Date::Easy::Datetime object whose time portion is always guaranteed to be midnight. In typical usage, you will either use the date constructor to convert a human-readable string to a date, or the today function to return today's date. Both are exported with the :all tag; nothing is exported by default.

Arithmetic operators (plus and minus) either add or subtract days to or from the date object. All methods are inherited from Date::Easy::Datetime.

Like their underlying datetime objects, date objects are immutable.

See Date::Easy for more general usage notes.




Returns the same as "today".


Takes the given epoch seconds, turns it into a datetime (in the local timezone), then throws away the time portion and constructs a date object with the remainder.

Date::Easy::Date->new($y, $m, $d)

Takes the given year, month, and day, and turns it into a date object. Month and day are human-centric (i.e., 1-based, not 0-based). Year should be a 4-digit year; if you pass in a 2-digit year, you get a year bewteen 1900 and 1999, even if you use the last 2 digits of the current year.


If the sole argument to new is a blessed object, attempts to convert that object to a date. Currently the only type of object that can be successfully converted is a Time::Piece.


Returns the current date (in the local timezone).


Takes the human-readable string and converts it to a date using the following heuristics:

  • If the string consists of exactly 8 digits, and the first two digits are between "10" and "28" (inclusive), treats it as a compact datestring in the form YYYYMMDD. Splits it up and passes year, month, and day to new.

  • Otherwise, if the string consists of nothing but digits (including an optional leading negative sign), treats it as a number of epoch seconds and passes it to new.

  • Otherwise, if the string contains no digits at all, removes any timezone specifier, then passes it to Time::ParseDate's parsedate function. If the result is defined, passes the resulting epoch seconds to new.

  • Otherwise if the string contains some digits, passes it to Date::Parse's strptime function. If the resulting six values are defined and in the proper ranges, passes the year, month, and day to new.

  • Otherwise if the results of calling strptime are unsatisfactory, removes any timezone specifier, then passes it to Time::ParseDate's parsedate function. If the result is defined, passes the resulting epoch seconds to new.

  • If parsedate returns undef (in either position), throws an "Illegal date" exception.

Though this sounds complicated, most of the time it just does what you meant and you don't need to think about it.


All accessors are inherited from Date::Easy::Datetime, so refer to those docs. Note that hour, minute, and second will always return 0 for a date object, and time_zone will always return 'UTC'. Likewise, is_local always returns false and is_utc (and its alias is_gmt) always return true.

Overridden Methods

A few methods inherited from Date::Easy::Datetime return different results in Date::Easy::Date.


Returns a list consisting of the year, month, and day, in that order, in the same ranges as returned by the "Accessors" in Date::Easy::Datetime. This differs from datetime's split in that the final three elements (hours, minutes, and seconds) are omitted, since they're always zero. Doesn't return anything useful in scalar context, so don't do that. Calling split in scalar context may eventually be changed to throw a warning or fatal error.







These methods throw exceptions if you call them for a date value, because they would adjust the time portion, and the time portion of a date value must always be midnight.

Other Methods

All other methods are also inherited from Date::Easy::Datetime, so refer to those docs.

Overloaded Operators


You can add an integer value to a date object. It adds that number of days and returns a new date object. The original date is not modified.


You can subtract an integer value from a date object. It subtracts that number of days and returns a new date object. The original date is not modified.

You can subtract one date from another; the result is the number of days you would have to add to the right-hand operand to get the left-hand operand (therefore, the result is positive when the left-hand side is a later date, and negative when the left-hand side is earlier). Currently the result of attempting to subtract a datetime from a date is undefined.


Because a number like "20090120" can be either a compact datestring (20-Jan-2009) or a valid number of epoch seconds (21-Aug-1970 12:35:20), there is a range of epoch seconds that you cannot pass in via date. That range is 26-Apr-1970 17:46:40 to 2-Dec-1970 15:33:19.

Any timezone portion specified in a string passed to date is completely ignored.

If you pass a 2-digit year to date, it will always come back in the 20th century:

    say date("2/1/17"); # Thu Feb  1 00:00:00 1917

Avoiding this is simple: always use 4-digit dates (which is a good habit to get into anyway). This could be considered a bug, since Time::Local uses a 50-year sliding window, which might be considered to be more correct behavior. However, by suffering this "bug," we avoid a bigger one (see RT/53413 and RT/105031).

See also "Limitations" in Date::Easy.


Buddy Burden <>


This software is Copyright (c) 2020 by Buddy Burden.

This is free software, licensed under:

  The Artistic License 2.0 (GPL Compatible)