Converting date and time to Unix epoch in Perl

Today I was working on a script, and one of the subroutines needed simple seconds-based arithmetics with time. As you probably remember fromĀ  my date and time in Unix scripts article, the easiest way to approach this task is to deal with the raw representation of date and time in Unix – the Unix epoch times. This post will show you how to convert standard dates into Unix epoch times in Perl.

Why would you want to convert timestamps to Unix epoch time?

Unix epoch time is an ever-growing counter which increments every second and shows the number of seconds elapsed since 00:00:00 UTC on January 1, 1970. Such numbers are pretty useless in their raw form for the tasks of confirming current time and date, but they’re perfect for measuring between two points in time.

Current epoch time in Perl

First things first. If you want to confirm the current Unix epoch time in Perl, here’s how you do it: just use the time() subroutine.

#!/bin/perl
print "Current (epoch) time: " . time() . "\n";

Converting regular date and time into epoch time

It’s equally easy to convert time into Unix epoch representation, for this you should use timegm() or localtime() subroutine from the Time::Local module.

timegm() has the following syntax:

$current = timegm($sec,$min,$hours,$day,$month,$year);

Important: While most of the parameters are self-explanatory, it is probably worth reminding that $year should be specified as a number like 109 and not 2009.
Also, the $month is not the number of a month, but a number of months since January. So, 0 will mean January itself, 1 will mean February, and 11 means December.

Here’s a fully working example, showing the countdown in seconds until midnight on the New Year’s Eve 2009:

#!/usr/bin/perl
#
use Time::Local;
#
$sec=59;
$min=59;
$hours=23;
$day=31;
$month=11;
$year=109;
#
$current = time();
print "Current (epoch) time: $current\n";
#
$newyear = timegm($sec,$min,$hours,$day,$month,$year);
print "New Year's Eve 2009: $newyear\n";
#
print "Only " .($newyear-$current) . " seconds to go\n";

When you save this script as epoch.pl and make the file executable, here’s what you’ll get if you run it:

# ./epoch.pl
Current (epoch) time: 1234911622
New Year's Eve 2009: 1262303999
Only 27392377 seconds to go

That’s it for today! Hope this little post will save you time when tacking next scripting challenge with Perl.

See also




Confirm the Day of the Week Based on a Timestamp

I recently created a Unix Questions and Answers page, if you have a Unix question – feel free to ask it there using the submit form and I’ll do my best to help you out.

Today’s Unix question is this:

How can we write a shell script in unix to find the day of the week when date is given?

The solution for this is even simpler: there’s no need for Unix scripting, all you need is to have GNU date command at your disposal. I’ve already shown you all the basic date/time calculations using this great tool, and that’s just another way of using it.

How to find a Day of the week based on timestamp

All you need is to know the base date. Let’s say I’m interested in October 16th, 2009. Here’s how easy it is to confirm that day will be Friday:

ubuntu$ date -d "Oct 16 2009" "+%a"
Fri

That’s it – enjoy!

See also:




Unix Scripting: Time and Date

If you have followed this blog for a while, you should remember how to use variables in Unix shell scripts.

Going further, I’d like to show you some basics of working with time and date in your scripts – generating all sorts of timestamps and timing some parts of your script for reporting purposes.

The history of (Unix) time

In case you didn’t know, time in Unix starts with a Unix epoch, sometimes also referred to as POSIX epoch. The Unix epoch is the time 00:00:00 UTC on January 1, 1970.

Most of Unix-like system today store and calculate this time according to Unix epoch, which means they all have an internal counter which counts the number of seconds elapsed since midnight of January 1, 1970.

As you can imagine, this is a pretty big number (it passed 1,000,000,000 seconds back in 2001, just so that you know), and reporting in directly would not be very useful to real humans. Because of this, most of Unix time and date reporting commands and functions do the conversion from Unix time into something more meaningful to the end user.

While for the vast majority of time and date related tasks this conversion is good, a task of timing certain events can sometimes benefit from using raw second counters and simply subtracting them when needed.

Getting Unix time and date

In Unix shells, the easiest way to get a current time and date is to use the date command:

ubuntu$ date
Tue Jun 10 10:46:07 IST 2008

date is a very smart command, and apart from this default behavior it supports template system for printing the current time and date – so you can use it to report only specific part of the time and date like the current hour or the day of a week or the year.

Read the man page for date (type man date in your shell prompt) to learn all the details, but this is how you use date output templates:

ubuntu$ date "+%b %d, %Y"
Jun 10, 2008

In this example, the %b parameter in this template represents the short name of the current month, %d is the day of the month, and %Y is the four-digit representation of the current year.

Timing parts of your Unix script

If you’re after timing some parts of your script, you’ll need to use two variables: one for saving the time before the start of an observed part of the script, and another one for saving the time after the same piece of code.

These two variables will be used to subtract the time and report the elapsed time in seconds, so in order to do this we’ll need the date command to report time in seconds. That’s why I’ve given you an introduction to Unix time earlier: date reports the number of seconds since the Unix epoch:

ubuntu$ date +%s
1213091896

If you run it just a few seconds later, you’ll see a different number:

ubuntu$ date +%s
1213091922

That’s why, if such values are saved and then subtracted, we’ll get the elapsed time in seconds.

Here’s a simple script showing how this is done:

#!/bin/bash
#
START=`date +%s`
echo "Script start time (Unix epoch): $START"
#
echo "- sleeping for 3 seconds..."
sleep 3
echo "- sleeping for 2 seconds more..."
sleep 2
#
FINISH=`date +%s`
echo "Script finish time (Unix epoch): $FINISH"
#
ELAPSED=`expr $FINISH - $START`
echo "Elapsed time: $ELAPSED"

And if you run it, you will see this output:

ubuntu$ /tmp/time-example.sh
Script start time (Unix epoch): 1213092131
- sleeping for 3 seconds...
- sleeping for 2 seconds more...
Script finish time (Unix epoch): 1213092131
Elapsed time: 5

That’s all I wanted to show you today. In future posts, I’ll show you a few more things you can do regarding timing and timestamps in Unix. Until then – good luck with your scripting, and feel free to ask if you need any more help!

See Also