Time::Piece - Object Oriented time objects
use Time::Piece;
my $t = localtime;
print "Time is $t\n";
print "Year is ", $t->year, "\n";
This module replaces the standard localtime and gmtime functions with implementations that return objects. It does so in a backwards compatible manner, so that using localtime/gmtime in the way documented in perlfunc will still return what you expect.
The module actually implements most of an interface described by Larry Wall on the perl5-porters mailing list here: https://www.nntp.perl.org/group/perl.perl5.porters/2000/01/msg5283.html
After importing this module, when you use localtime or gmtime in a scalar context, rather than getting an ordinary scalar string representing the date and time, you get a Time::Piece object, whose stringification happens to produce the same effect as the localtime and gmtime functions.
The primary way to create Time::Piece objects is through the localtime and gmtime functions. There is also a new() constructor which is the same as localtime(), except when passed a Time::Piece object, in which case it's a copy constructor.
The following methods are available on the object:
$t->sec # also available as $t->second
$t->min # also available as $t->minute
$t->hour # 24 hour
$t->mday # also available as $t->day_of_month
$t->mon # 1 = January
$t->_mon # 0 = January
$t->year # based at 0 (year 0 AD is, of course 1 BC)
$t->_year # year minus 1900
$t->yy # 2 digit year
$t->monname # Feb
$t->month # same as $t->monname
$t->fullmonth # February
$t->wday # 1 = Sunday
$t->_wday # 0 = Sunday
$t->day_of_week # 0 = Sunday
$t->wdayname # Tue
$t->day # same as wdayname
$t->fullday # Tuesday
$t->hms # 12:34:56
$t->hms(".") # 12.34.56
$t->time # same as $t->hms
$t->ymd # 2000-02-29
$t->date # same as $t->ymd
$t->mdy # 02-29-2000
$t->mdy("/") # 02/29/2000
$t->dmy # 29-02-2000
$t->dmy(".") # 29.02.2000
$t->datetime # 2000-02-29T12:34:56 (ISO 8601)
$t->cdate # Tue Feb 29 12:34:56 2000
"$t" # same as $t->cdate
$t->strftime(FORMAT) # same as POSIX::strftime (without the overhead
# of the full POSIX extension)
$t->strftime() # "Tue, 29 Feb 2000 12:34:56 GMT"
$t->epoch # seconds since the epoch
$t->julian_day # number of days since Julian period began
$t->mjd # modified Julian date (JD-2400000.5 days)
$t->week # week number (ISO 8601)
$t->yday # also available as $t->day_of_year, 0 = Jan 01
$t->tzoffset # timezone offset in a Time::Seconds object
$t->isdst # also available as $t->daylight_savings
The isdst method returns:
0 for GMT/UTC times (they never have DST)
0 or 1 for local times depending on whether DST is active
Automatically calculated if unknown
The tzoffset method returns the offset from UTC as a Time::Seconds object. For GMT/UTC times, this always returns 0. For local times, it calculates the actual offset including any DST adjustment.
$t->is_leap_year # true if it's a leap year
$t->month_last_day # 28-31
$t->time_separator($s) # set the default separator (default ":")
$t->date_separator($s) # set the default separator (default "-")
$t->day_list(@days) # set the default weekdays
$t->mon_list(@days) # set the default months
Time::Piece->strptime(STRING, FORMAT)
# see strptime man page. Creates a new
# Time::Piece object
Note: localtime and gmtime are not listed above. If called as methods on a Time::Piece object, they act as constructors, returning a new Time::Piece object for the current time. In other words: they're not useful as methods.
It's possible to use simple addition and subtraction of objects:
use Time::Seconds;
my $seconds = $t1 - $t2;
$t1 += ONE_DAY; # add 1 day (constant from Time::Seconds)
The following are valid ($t1 and $t2 are Time::Piece objects):
$t1 - $t2; # returns Time::Seconds object
$t1 - 42; # returns Time::Piece object
$t1 + 533; # returns Time::Piece object
Note: All arithmetic uses epoch seconds (UTC). When daylight saving time (DST) changes occur:
Adding seconds works on UTC time, so adding 3600 seconds during DST transition from 1:30 AM gives 3:30 AM (not 2:30 AM, which doesn't exist during "spring forward")
Subtracting across DST transitions may differ from wall-clock expectations due to skipped or repeated hours
Two methods handle calendar arithmetic differently than seconds-based math:
$t = $t->add_months(6);
$t = $t->add_years(5);
Important behaviors:
These preserve the day-of-month number, which can cause overflow (Jan 31 + 1 month = Mar 3, since "Feb 31" doesn't exist)
Wall-clock time is preserved across DST transitions
Order matters: add_months(1) then + 86400 gives different results than + 86400 then add_months(1)
Calling the truncate method returns a copy of the object but with the time truncated to the start of the supplied unit.
$t = $t->truncate(to => 'day');
This example will set the time to midnight on the same date which $t had previously. Allowed values for the "to" parameter are: "year", "quarter", "month", "day", "hour", "minute" and "second".
Date comparisons are also possible, using the full suite of "<", ">", "<=", ">=", "<=>", "==" and "!=".
All comparisons use epoch seconds, so they work correctly across timezones:
my $t1 = localtime;
my $t2 = gmtime;
if ($t1 > $t2) { # Compares actual moments in time, not clock values
# ...
}
Time::Piece objects can also be compared as strings using cmp:
if ($t1 cmp "2024-01-15") { # Compares against cdate format
# ...
}
Time::Piece provides flexible date parsing via the built-in strptime() function (from FreeBSD).
For more information on acceptible formats and flags for strptime see "man strptime" on unix systems. Alternatively look here: http://www.unix.com/man-page/FreeBSD/3/strftime/
my $t = Time::Piece->strptime("Sunday 3rd Nov, 1943",
"%A %drd %b, %Y");
print $t->strftime("%a, %d %b %Y");
Outputs:
Wed, 03 Nov 1943
The default format string is "%a, %d %b %Y %H:%M:%S %Z", so these are equivalent:
my $t1 = Time::Piece->strptime($string);
my $t2 = Time::Piece->strptime($string, "%a, %d %b %Y %H:%M:%S %Z");
When parsing incomplete date strings, you can provide defaults for missing components in several ways:
Array Reference - Standard time components (as returned by localtime):
my @defaults = localtime();
my $t = Time::Piece->strptime("15 Mar", "%d %b",
{ defaults => \@defaults });
Hash Reference - Specify only needed components:
my $t = Time::Piece->strptime("15 Mar", "%d %b",
{ defaults => {
year => 2023,
hour => 14,
min => 30
} });
Valid keys: sec, min, hour, mday, mon, year, wday, yday, isdst
Note: For the year parameter numbers less than 1000 are treated as an offset from 1900. Whereas numbers larger than 1000 are treated as the actual year.
Time::Piece Object - Uses all components from the object:
my $base = localtime();
my $t = Time::Piece->strptime("15 Mar", "%d %b",
{ defaults => $base });
Note: In all cases, parsed values always override defaults. Only missing components use default values.
By default, strptime returns GMT objects when called as a class method:
# Returns GMT (c_islocal = 0)
Time::Piece->strptime($string, $format)
To get local time objects, you can:
# Call as instance method on localtime object
localtime()->strptime($string, $format)
# Use explicit islocal option
Time::Piece->strptime($string, $format, { islocal => 1 })
# Pass a local Time::Piece object as defaults
my $local = localtime();
Time::Piece->strptime($string, $format, { defaults => $local })
By default, strptime only parses English day and month names, while strftime uses your system locale. This can cause parsing failures for non-English dates.
To parse localized dates, call Time::Piece->use_locale() to build a list of your locale's day and month names:
# Enable locale-aware parsing (global setting)
Time::Piece->use_locale();
# Now strptime can parse names in your system locale
my $t = Time::Piece->strptime("15 Marzo 2024", "%d %B %Y");
Note: This is a global change affecting all Time::Piece instances.
You can also override the day/month names manually:
my @days = qw( Domingo Lunes Martes Miercoles Jueves Viernes Sabado );
my $spanish_day = localtime->day(@days);
my @months = qw( Enero Febrero Marzo Abril Mayo Junio
Julio Agosto Septiembre Octubre Noviembre Diciembre );
print localtime->month(@months);
Set globally with:
Time::Piece::day_list(@days);
Time::Piece::mon_list(@months);
Time::Piece's strptime() function has some limited support for parsing timezone information through two format specifiers: %z and %Z
Added in version 1.38. Prior to that, these flags were mostly ignored. Consider the current implementation somewhat "alpha" and in need of feedback.
The %z specifier parses numeric timezone offsets (format: +HHMM or -HHMM):
my $t = Time::Piece->strptime("2024-01-15 15:30:00 +0500",
"%Y-%m-%d %H:%M:%S %z");
print $t->hour; # prints 10 (converted to UTC: 15:30 - 5:00)
Key behaviors:
Offsets are applied to convert to UTC (+0500 means "5 hours ahead of UTC")
Valid range: -1200 to +1400 with minutes less than 60
For local objects (islocal == 1), the result is converted to system timezone
Times parsed with timezone information default to GMT. To convert to local time:
# Parse and convert to local timezone
my $t = Time::Piece->strptime("2024-01-15 15:30:00 +0500",
"%Y-%m-%d %H:%M:%S %z",
{ islocal => 1 });
# Result: 10:30 UTC converted to your local timezone
The %Z specifier currently only recognizes "GMT" and "UTC" (case-sensitive). Other timezone names are parsed but ignored:
# GMT/UTC recognized and handled
my $t1 = Time::Piece->strptime("2024-01-15 10:30:00 GMT",
"%Y-%m-%d %H:%M:%S %Z");
print $t1->hour; # prints 10 (no adjustment)
# Other timezones parsed but ignored
my $t2 = Time::Piece->strptime("2024-01-15 10:30:00 PST",
"%Y-%m-%d %H:%M:%S %Z");
print $t2->hour; # prints 10 (PST ignored - no adjustment)
Note: Full timezone name support is not currently implemented. For reliable timezone handling beyond GMT/UTC, consider using the DateTime module.
To override localtime and gmtime everywhere:
use Time::Piece ':override';
This replaces Perl's built-in functions with Time::Piece versions globally.
Note that when using perl in the default build configuration on Win32 (specifically, when perl is built with PERL_IMPLICIT_SYS), each perl interpreter maintains its own copy of the environment and only the main interpreter will update the process environment seen by strftime.
Therefore, if you make changes to $ENV{TZ} from inside a thread other than the main thread then those changes will not be seen by strftime if you subsequently call that with the %Z formatting code. You must change $ENV{TZ} in the main thread to have the desired effect in this case (and you must also call _tzset() in the main thread to register the environment change).
Furthermore, remember that this caveat also applies to fork(), which is emulated by threads on Win32.
This module internally uses the epoch seconds system that is provided via the perl time() function and supported by gmtime() and localtime().
If your perl does not support times larger than 2^31 seconds (Perl versions < 5.12) then this module is likely to fail at processing dates beyond the year 2038. If that is not an option, use the DateTime module which has support for years well into the future and past.
Matt Sergeant, matt@sergeant.org Jarkko Hietaniemi, jhi@iki.fi (while creating Time::Piece for core perl)
Copyright 2001, Larry Wall.
This module is free software, you may distribute it under the same terms as Perl.
The excellent Calendar FAQ at http://www.tondering.dk/claus/calendar.html
The test harness leaves much to be desired. Patches welcome.
Proper UTF8 support