NAME
Time::Keeper::Date - a date with no time of day
VERSION
Version 0.11
SYNOPSIS
use Time::Keeper;
my $d = Time::Keeper::Date->new(year => 2026, month => 10, day => 15);
my $d = Time::Keeper::Date->today(zone => 'Europe/London');
my $d = Time::Keeper::Date->parse('2026-10-15');
my $d = $t->to_date; # from a Time::Keeper value
$d->day_of_week; # 4, Thursday
$d->plus(months => 1); # 2026-11-15
$d->next(day_of_week => 1); # the Monday after
$d->format('EEEE d MMMM y'); # Thursday 15 October 2026
$d->at(hour => 9, zone => 'Europe/London'); # a Time::Keeper value
"$d"; # 2026-10-15
DESCRIPTION
A date with no time of day and no zone: a birthday, a due date, a day in a calendar. It is not a Time::Keeper value and does not pretend to be one: it has no hour, no epoch and no zone, a pattern letter that needs a time of day is an error rather than a fabricated 00, and it compares only with another date. What it shares with a value it shares exactly: the same calendar arithmetic (months first, then days, so $a + ($b - $a) is $b), the same CLDR names and formats in every locale, the same parsers, the same serialisation hooks.
A date in a locale carries that locale into its names and formats, as a value does; see "LOCALES" in Time::Keeper.
CONSTRUCTORS
new
my $d = Time::Keeper::Date->new(year => 2026, month => 10, day => 15);
my $d = Time::Keeper::Date->new(year => 2026, month => 10, day => 15, locale => 'fr');
The date given. month and day default to 1. A day the month does not have is an error. There are no time keys and no zone.
last_day_of_month
from_day_of_year
from_iso_week
Time::Keeper::Date->last_day_of_month(year => 2024, month => 2); # 2024-02-29
Time::Keeper::Date->from_day_of_year(year => 2026, day_of_year => 288);
Time::Keeper::Date->from_iso_week(year => 2026, week => 42, day => 4);
As "new" in Time::Keeper's aliases, without a time: the last day of the month, the day of the year, the day of the ISO week (day 1 Monday to 7 Sunday, default Monday).
today
my $d = Time::Keeper::Date->today;
my $d = Time::Keeper::Date->today(zone => 'Asia/Tokyo');
Today's date in the zone, UTC by default; it reads the clock "TESTING" in Time::Keeper describes.
from_epoch_days
my $d = Time::Keeper::Date->from_epoch_days(20741); # 2026-10-15
The date that many days after 1 January 1970; negative for before.
parse
strptime
parse_cldr
Time::Keeper::Date->parse('2026-10-15');
Time::Keeper::Date->parse('2026-W42-4');
Time::Keeper::Date->parse('2026-288');
Time::Keeper::Date->strptime('15/10/2026', '%d/%m/%Y');
Time::Keeper::Date->parse_cldr('15 octobre 2026', 'd MMMM y', locale => 'fr');
As Time::Keeper's, but giving a date. parse reads the ISO 8601 date forms, calendar, week and ordinal, extended and basic, and refuses text that names a time of day, an offset or a zone: a date holds none of them. A month alone is its first day and a week alone its Monday. Under a pattern, the pattern says what the text holds and the date keeps the date: a %H in a strptime pattern is read and dropped. Each takes locale.
try_new
try_parse
try_strptime
try_parse_cldr
As the method without try_, but undef where it would die, with $@ left as it was.
ACCESSORS
year
month
day
day_of_week
day_of_year
quarter
day_of_quarter
week
week_year
week_of_month
is_leap_year
days_in_month
days_in_year
days_in_quarter
is_weekend
is_weekday
As "ACCESSORS" in Time::Keeper; week and week_year take locale => 1 for the locale's weeks.
epoch_days
Days since 1 January 1970, negative before it; the inverse of "from_epoch_days".
locale
The locale's code.
month_name
month_abbr
day_name
day_abbr
era_name
era_abbr
quarter_name
quarter_abbr
The locale's names, as "month_name" in Time::Keeper and the rest.
NEW DATES FROM OLD
with
$d->with(day => 1);
$d->with(day => 'last');
$d->with(day_of_year => 60);
$d->with(week => 42); # keeps the day of the week
$d->with(day_of_week => 3); # the Wednesday of the same ISO week
As "with" in Time::Keeper, for the date's parts.
in_locale
The same date in another locale.
to_year_month
to_month_day
$d->to_year_month; # a Time::Keeper::YearMonth, 2026-10
$d->to_month_day; # a Time::Keeper::MonthDay, --10-15
at
my $t = $d->at(hour => 9, minute => 30, zone => 'Europe/London');
my $t = $d->at($time_of_day, zone => 'Europe/London', gap => 'forward');
my $t = $d->at(zone => 'America/Sao_Paulo'); # midnight, or the first moment after it
The Time::Keeper value at that time of day on this date in the zone (UTC by default), with the date's locale. The time is given by its parts, or as a Time::Keeper::Time first. gap and overlap as for "new" in Time::Keeper; with no time given, a midnight the clocks skipped gives the first moment that happened, as "today" in Time::Keeper does.
ARITHMETIC
plus
minus
$d->plus(months => 1);
$d->plus(years => 1, months => 2, weeks => 3, days => 4);
$d->plus(months => 1, end_of_month => 'limit');
$d->plus($duration);
$d->minus($other_date); # a duration
Years, months, weeks and days, by name or as a Time::Keeper::Duration, with end_of_month as "plus" in Time::Keeper takes it. Hours and anything smaller are an error: a date has no clock to add them to. minus with another date gives the duration from it to this one, months then days ("ARITHMETIC" in Time::Keeper). The operators + and - do the same.
delta_days
delta_md
The duration between two dates, in days alone, or in months and days; never negative.
truncate
round
end_of
$d->truncate(to => 'month'); # the first
$d->truncate(to => 'week', week_start => 'locale');
$d->end_of(to => 'year'); # 31 December
$d->round(to => 'month', mode => 'floor');
To a year, quarter, month or week, as "truncate" in Time::Keeper; end_of gives the period's last day.
next
previous
nth_in_month
last_in_month
$d->next(day_of_week => 1);
$d->next(day_of_week => 1, or_same => 1);
$d->nth_in_month(day_of_week => 4, n => 3);
$d->last_in_month(day_of_week => 7);
As "next" in Time::Keeper and the rest, without gap and overlap.
COMPARING AND PRINTING
compare
Time::Keeper::Date->compare($a, $b); # -1, 0 or 1
The operators <=>, ==, < and so on do the same. A date compares only with another date; a Time::Keeper value or a year and month beside it is an error.
iso8601
TO_JSON
2026-10-15; years outside 0000 to 9999 with a sign and six digits. "$d" is the same.
ymd
mdy
dmy
date
As "ymd" in Time::Keeper; date is ymd with hyphens.
FORMATTING
strftime
format
format_date
format_skeleton
$d->format('EEEE d MMMM y');
$d->strftime('%A %-d %B %Y');
$d->format_date('full');
$d->format_skeleton('yMMMd');
As Time::Keeper's, for the date's letters. A letter that needs a time of day or a zone (H, a, z, %T, %c, %s and their kin) is an error naming it, not a fabricated value; "at" in Time::Keeper gives a value when a time is wanted.
SERIALISATION
STORABLE_freeze
STORABLE_thaw
FREEZE
THAW
Storable's and the Types::Serialiser protocol's hooks, as "SERIALISATION" in Time::Keeper: the frozen text carries the kind, so a frozen date thaws only as a date.
utc_rd_values
The Rata Die day and zero seconds, for DateTime's from_object.
SEE ALSO
Time::Keeper, Time::Keeper::YearMonth, Time::Keeper::MonthDay.
AUTHOR
LNATION, <email at lnation.org>
LICENSE AND COPYRIGHT
This software is Copyright (c) 2026 by LNATION.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)