Perl date and time
last modified October 8, 2026
In this article we work with dates and times in Perl. We cover epoch seconds,
the localtime and gmtime functions, formatting with
POSIX::strftime, building epoch values with POSIX::mktime,
and the Time::Piece module.
Perl stores a point in time as an integer number of seconds since the epoch,
which is 00:00:00 UTC on January 1, 1970. The core functions localtime
and gmtime convert such a number into calendar fields. The examples
that print local times were run with the local time zone set to UTC
(TZ=UTC); in another time zone the hours and epoch values differ.
Perl time function
The time function returns the current time as seconds since the
epoch. Its value changes every second, so the example prints only facts that
do not change between runs.
#!/usr/bin/perl use v5.34.0; use warnings; my $now = time; say "time() returns an integer: ", ($now =~ /^\d+$/ ? "yes" : "no"); say "The value is after 2020-01-01: ", ($now > 1577836800 ? "yes" : "no");
The value 1577836800 is the epoch time of January 1, 2020 at midnight UTC.
$ ./time.pl time() returns an integer: yes The value is after 2020-01-01: yes
Perl localtime in scalar context
When localtime is called in scalar context, it returns a string
with the date and time in the local time zone. We pass a fixed epoch value so
the output is repeatable.
#!/usr/bin/perl use v5.34.0; use warnings; my $t = localtime(1700000000); say "Scalar localtime: $t";
The string has the form Tue Nov 14 22:13:20 2023, that is, the
weekday, month, day, time, and year.
$ TZ=UTC ./localtime_scalar.pl Scalar localtime: Tue Nov 14 22:13:20 2023
Perl localtime in list context
In list context, localtime returns nine values: sec,
min, hour, mday, mon,
year, wday, yday, and isdst.
Two offsets are easy to forget: year counts years since 1900, and
mon is zero-based, so January is 0 and December is 11.
#!/usr/bin/perl
use v5.34.0;
use warnings;
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
= localtime(1700000000);
printf "Date: %04d-%02d-%02d\n", $year + 1900, $mon + 1, $mday;
printf "Time: %02d:%02d:%02d\n", $hour, $min, $sec;
say "wday: $wday (0 = Sunday)";
say "yday: $yday (0-based)";
say "isdst: $isdst";
printf "Date: %04d-%02d-%02d\n", $year + 1900, $mon + 1, $mday;
We add 1900 to $year and 1 to $mon to get the
calendar year and month.
say "wday: $wday (0 = Sunday)"; say "yday: $yday (0-based)";
The weekday is 0 for Sunday through 6 for Saturday. The day of the year
yday starts at 0 for January 1. The isdst flag is 1
when daylight saving time is in effect and 0 otherwise.
$ TZ=UTC ./localtime_list.pl Date: 2023-11-14 Time: 22:13:20 wday: 2 (0 = Sunday) yday: 317 (0-based) isdst: 0
Perl gmtime
The gmtime function works like localtime, but it
returns UTC values. It does not depend on the time zone, so it is useful for
fixed reference points. gmtime(0) is the epoch itself.
#!/usr/bin/perl use v5.34.0; use warnings; my $t = gmtime(0); say "Scalar: $t"; my @parts = gmtime(0); say "List: @parts";
The list form has the fields in the order sec, min, hour, mday, mon,
year, wday, yday, isdst. For the epoch, the year field is 70 (1970), and
the weekday field is 4 (Thursday).
$ ./gmtime.pl Scalar: Thu Jan 1 00:00:00 1970 List: 0 0 0 1 0 70 4 0 0
Perl strftime
The strftime function from the core POSIX module
formats a list of time fields using a format string, in the same way as the C
library function. Here we use gmtime to get the fields.
#!/usr/bin/perl
use v5.34.0;
use warnings;
use POSIX qw(strftime);
my @t = gmtime(1700000000);
say strftime("%Y-%m-%d %H:%M:%S", @t);
say strftime("%A, %B %d, %Y", @t);
say strftime("%a %b %e %I:%M %p", @t);
The format codes %Y, %m, and %d give
the year, month, and day. %A and %B are the full
weekday and month names, %e is the day padded with a space, and
%I and %p give the 12-hour clock and AM/PM marker.
$ ./strftime.pl 2023-11-14 22:13:20 Tuesday, November 14, 2023 Tue Nov 14 10:13 PM
Perl mktime
The mktime function from POSIX does the reverse of
localtime: it takes the calendar fields and returns an epoch value
in the local time zone. The same offsets apply: the year is counted from 1900
and the month is zero-based.
#!/usr/bin/perl use v5.34.0; use warnings; use POSIX qw(mktime); # year is years since 1900, month is 0-based: 123 = 2023, 11 = December my $epoch = mktime(0, 0, 12, 25, 11, 123); say "Epoch: $epoch"; say "Back: ", scalar localtime($epoch);
We build the epoch for December 25, 2023 at 12:00:00. We then convert the
epoch back with localtime to check the result.
$ TZ=UTC ./mktime.pl Epoch: 1703505600 Back: Mon Dec 25 12:00:00 2023
Perl Time::Piece
Time::Piece is a core module, included with Perl since version
5.10. It provides an object interface to dates and times. When it is loaded,
localtime and gmtime return objects in scalar
context, and the object has methods such as ymd, hms,
and strftime.
#!/usr/bin/perl
use v5.34.0;
use warnings;
use Time::Piece;
my $t = gmtime(1700000000);
say "Date: ", $t->ymd;
say "Time: ", $t->hms;
say "Month: ", $t->monname;
say "Day: ", $t->fullday;
say "Custom: ", $t->strftime("%d.%m.%Y");
my $t2 = Time::Piece->strptime("2024-03-01", "%Y-%m-%d");
printf "Days until 2024-03-01: %.2f\n", ($t2 - $t)->days;
Subtracting two Time::Piece objects returns a
Time::Seconds object, whose days method gives the
difference in days. The strptime method parses a string into a
Time::Piece object.
$ ./timepiece.pl Date: 2023-11-14 Time: 22:13:20 Month: Nov Day: Tuesday Custom: 14.11.2023 Days until 2024-03-01: 107.07
Perl elapsed time
To measure elapsed time in a real program, store time in a
variable before the work starts and subtract it afterwards. In this example we
use two fixed epoch values, so the result is the same on every run.
#!/usr/bin/perl use v5.34.0; use warnings; my $start = 1700000000; my $end = 1700093784; my $elapsed = $end - $start; my $days = int($elapsed / 86400); my $hours = int(($elapsed % 86400) / 3600); my $minutes = int(($elapsed % 3600) / 60); my $seconds = $elapsed % 60; say "Elapsed seconds: $elapsed"; printf "Elapsed: %d days, %02d:%02d:%02d\n", $days, $hours, $minutes, $seconds;
my $elapsed = $end - $start;
The difference between two epoch values is the number of seconds elapsed.
my $days = int($elapsed / 86400); my $hours = int(($elapsed % 86400) / 3600);
There are 86400 seconds in a day and 3600 seconds in an hour. Integer division and the modulus operator split the total into days, hours, minutes, and seconds.
$ ./elapsed.pl Elapsed seconds: 93784 Elapsed: 1 days, 02:03:04
In this article we have covered epoch seconds, localtime and
gmtime, strftime, mktime, and
Time::Piece in Perl.
Author
List all Perl tutorials.