Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
Date::Piece(3)	      User Contributed Perl Documentation	Date::Piece(3)

       Date::Piece - efficient dates with Time::Piece interoperability

	 use Date::Piece qw(date);

	 my $date = date('2007-11-22');
	 my $time = $date->at('16:42:35');

	 print $time, "\n"; # is a Time::Piece

       You can also start from a Time::Piece object.

	 use Time::Piece;
	 use Date::Piece;

	 my $time = localtime;
	 my $date = $time->date; # also	ymd()

	 # seven days later
	 print $date, "\n";

	 # seven days later at the original time
	 print $date->at($time), "\n";

       This module allows you to do nominal math on dates.  That is, rather
       than worrying about time	zones and DST while adding increments of
       24*60**2	seconds	to a date&time object, you simply discard the time
       component and do	math directly on the date.  If you need	a time-of-day
       on the calculated date, the at()	method returns a Time::Piece object,
       thus allowing you to be specific	about the endpoints of a nominal

       This is useful for constructs such as "tomorrow", "yesterday", "this
       time tomorrow", "one week from today", "one month later", "my 31st
       birthday", and various other not-necessarily-numeric intervals on the
       arbitrary and edge-case-laden division of time known by most earthlings
       as "the calendar."  That	is, adding days	or months is analogous to
       counting	squares	or turning pages on a calendar.

       This module extends Date::Simple	and connects it	to Time::Piece.	 See
       Date::Simple for	more details.

       A Date::Piece object never changes.  This means that methods like
       add_months() always return a new	object.

       This does not appear to be true with constructs such as "$date++" or
       "$date+=7", but what is actually	happening is that perl treats the
       variable	as an lvalue and assigns the new object	to it.	Thus, the
       following is true:

	 my $also_date = my $date = today;
	 $date > $also_date;

       Where Date::Simple returns false	for invalid dates, I throw errors.

Convenient Syntax
       You may import the functions 'date' and 'today' as well as the unit-
       qualifiers 'years', 'months', and 'weeks'.

       When loaded as -MDate::Piece with perl -e (and/or -E in 5.10), these
       extremely short versions	are exported by	default:

	 years	=> 'Y',
	 months	=> 'M',
	 weeks	=> 'W',
	 date	=> 'D',
	 today	=> 'CD', # mnemonic: Current Date

       You may unimport	any imported functions with the	'no Date::Piece'

       This returns the	current	date.  Don't be	afraid to use it in

	 my $today = today;
	 my $tomorrow =	today +	1;

	 my $new_year_is_coming	= date('2007-12-31');

       Equivalent to Date::Piece->new('2007-12-31');

       Also takes year,	month, day arguments.

	 my $d = date($year, $month, $day);

       Clean-out the imported methods from your	namespace.

	 no Date::Piece;

       Takes the same arguments	as date().

       TODO paste most of the Date::Simple documentation here?

   Note: lack of complete API compatibility with Time::Piece
       Ideally,	we should have the Time::Piece API, but	Date::Simple doesn't
       do that.	 I'm trying to avoid a complete	fork of	Date::Simple, but will
       likely need to do that just to make e.g.	month()	do the same thing that
       it does in Time::Piece.	Ultimately, a Date::Piece should act exactly
       like a Time::Piece where	the time is always midnight (which implies
       that adding seconds upgrades the	result to a Time::Piece	and etc.)






       Returns the day of the week (0-6) with Monday = 0 (as per ISO 8601.)

	 my $dow = $date->iso_dow;

       See day_of_week() if you	want Sunday as the first day (as in

       Returns 1-7 where Monday	is 1.

	 my $wday = $date->iso_wday;

Setting	the Time on a Date
       Returns a Time::Piece object at the given time on the date $date.

	 my $timepiece = $date->at($time);

       $time can be in 24-hour format (seconds optional) or have an 'am' or
       'pm' (case insensitive) suffix.

       $time may also be of the	form '1268s', which will be taken as a number
       of seconds to be	added to midnight on the given day (and	may be

       The time	is constructed via Time::Local.	 For concerns about daylight
       savings,	see the	caveats	in Time::Local.

       If $time	is a Time::Piece from a	different time zone, we	*should*
       respect that, but currently do the wrong	thing.

       These are all very simple, but convenient.

       January 1st of the year containing $date.

	 my $start = $date->start_of_year;

       December	31st of	the year containing $date.

	 my $end = $date->end_of_year;

       Returns the 1st of the month containing $date.

	 my $start = $date->start_of_month;

       Returns the last	day of the month containing $date.

	 my $end = $date->end_of_month;

       Returns the number of days in the month containing $date.

	 my $num = $date->days_in_month;

       See also	"Date::Simple::days_in_month($year, $month)".

       Returns true if Date is in a leap year.

	 my $bool = $date->leap_year;

       See also	"Date::Simple::leap_year($year)".

       Returns a list ala $start..$end (because	overloading doesn't work with
       the '..'	construct.)  Will work forwards	or backwards.

	 my @list = $date->thru($other_date);

       Returns a subref	which iterates through the dates between $date and
       $other_date (inclusive.)

	 my $subref = $date->iterator($other_date);
	 while(my $day = $subref->()) {
	   # do	something with $day

Fuzzy Math
       We can do math with months and years as long as you're flexible about
       the day of the month.  The theme	here is	to keep	the answer within the
       destination calendar month rather than adding e.g. 30 days.

       Returns a valid date even if the	given day is beyond the	last day of
       the month (returns the last day of that month.)

	 $date = adjust_day_of_month($y, $m, $maybe_day);

       Adds $n nominal months to $date.	 This will just	be a simple increment
       of the months (rolling-over at 12) as long as the day part is less than
       28.  If the destination month doesn't have as many days as the origin
       month, the answer will be the last day of the destination month (via

	 my $shifted = $date->add_months($n);

       Note that if $day > 28 this is not reversible.  One should not rely on
       it for incrementing except in trivial cases where $day <= 28 (because
       calling $date = $date->add_months(1) twice is not necessarily the same
       result as $date = $date->add_months(2).)

       Equivalent to adding $n*12 months.

	 my $shifted = $date->add_years($n);

Year, Month, and etc "units"
       The constants 'years', 'months',	and 'weeks' may	be multiplied by an
       integer and added to (or	subtracted from) a date.

	 use Date::Piece qw(today years);
	 my $distant_future = today + 10*years;

	 perl -MDate::Piece -e 'print CD+10*Y, "\n";'

       The unit	objects	stringify as e.g. '10years'.

       You may also divide time	units by a number as long as the result	is an
       integer.	 You may not use units as a divisor.

       Any math	done on	these units which yields other than an integer will
       throw a run-time	error.

       Also available are 'centuries' and 'days' (the latter is	convenient as
       a stricture to ensure that your days are	integers.)

       Conversion between these	units only makes sense for centuries =>	years
       and weeks => days, but is currently not available.

	 $date = $date->_add($thing);

	 $date = $date->_subtract($thing);

       These all assume	imported syntactical sugar ala:

	 use Date::Piece qw(date today years months weeks);
	 use Time::Piece;

       Turning 40 is pretty arbitrary, but alarming!

	 my $bd	= date('1970-12-02');
	 my $big40 = $bd+40*years;

	 $SIG{ALRM} = sub { print "dude!  You're 'old' now.\n";	exit; }
	 my $eggtimer =	localtime - $big40->at('06:57');

	 while(1) {
	   my $countdown = $big40-today;
	   print "$countdown days till the top of the hill\n";

       Wake me when the	ball drops (in my time zone.)

	 my $date = today+1*years;
	 $date = $date->start_of_year;
	 $SIG{ALRM} = sub { print "Happy new year!\n"; exit; }
	 alarm(localtime - $date->at('0s'));

       Eric Wilhelm @ <ewilhelm	at cpan	dot org>

       If you found this module	on CPAN, please	report any bugs	or feature
       requests	through	the web	interface at <>.  I will be
       notified, and then you'll automatically be notified of progress on your
       bug as I	make changes.

       If you pulled this development version from my /svn/, please contact me

       Copyright (C) 2007 Eric L. Wilhelm, All Rights Reserved.

       Absolutely, positively NO WARRANTY, neither express or implied, is
       offered with this software.  You	use this software at your own risk.
       In case of loss,	no person or entity owes you anything whatsoever.  You
       have been warned.

       This program is free software; you can redistribute it and/or modify it
       under the same terms as Perl itself.

perl v5.32.1			  2021-08-27			Date::Piece(3)

NAME | SYNOPSIS | ABOUT | Immutable | Validation | Convenient Syntax | Functions | Methods | Setting the Time on a Date | Endpoints | Fuzzy Math | Year, Month, and etc "units" | Examples | Constructor | AUTHOR | BUGS | COPYRIGHT | NO WARRANTY | LICENSE

Want to link to this manual page? Use this URL:

home | help