Thomas Owens
Thomas Owens

Reputation: 116197

How can I use Perl to do datetime comparisons and calculate deltas?

I extracted year, month, day, hour, minute, second, and millisecond data from human readable text (it wasn't in a timestamp format, but rather something like "X started at HH:MM:SS.SSS on DD MMM YYYY and ended at HH:MM:SS.SSSS on DD MMM YYYY"), so for each recorded event, I have each of the values.

However, I need to turn those into some kind of timestamp so I can do math on it - I want to determine how long the event lasted (end time - start time). I was hoping the time function would take parameters so I can create two arbitrary times, but that doesn't appear to be the case.

If possible, I would like to stick with functions available in the core Perl libraries or scripts that I can add to the project, since getting CPAN modules installed on the target machines would just make a headache for everyone, if it is even possible to get the modules through the security restrictions.

Upvotes: 2

Views: 5023

Answers (5)

Sinan Ünür
Sinan Ünür

Reputation: 118166

If you were only interested in comparing times,

my $ts1 = sprintf( '%4.4d%2.2d%2.2d%2.2d%2.2d%3.3d', 
                   $year1, $month1, $mday1, $hour1, $min1, $sec1, $ms1 );

to

my $ts2 = sprintf( '%4.4d%2.2d%2.2d%2.2d%2.2d%3.3d', 
                   $year2, $month2, $mday2, $hour2, $min2, $sec2, $ms2 );

using cmp would be sufficient.

To do arithmetic on these times, use Time::Local to get seconds since epoch and then add the $ms1/1000 to that value.

my $time1 = timelocal($sec1, $min1, $hour1, $mday1, $mon1, $year1) + $ms1/1000;

Upvotes: 2

Telemachus
Telemachus

Reputation: 19725

In terms of built-ins these may be helpful:

  1. POSIX (for mktime and strftime)
  2. Time::Piece, Time::Local and Time::Seconds. These are all standard in Perl 5.10, but may not be available by default on earlier systems.

That said, time/date calculations are complex. If the only obstacle is a few headaches installing modules (rather than a company policy forbidding them), I would really recommend looking at CPAN.

Edit: I see from your comment on another post that there are company restrictions. You should update your original post, since there's a big difference between "headaches" and "security restrictions." In any case, DateTime and Date::Manip are worth looking at. Even if you don't install them, you can get a lot out of reading their source.

Upvotes: 2

Stefan Kangas
Stefan Kangas

Reputation: 505

You want the CPAN module DateTime. Here's an introduction.

On a Debian GNU/Linux or Ubuntu system, simply run:

apt-get install libdatetime-perl

to install the module.

Upvotes: 7

Satanicpuppy
Satanicpuppy

Reputation: 1587

You can do it with Time:Local. It's basically the reverse of the built in "localtime" function, so you can generate a timestamp from a standard date.

Upvotes: 3

C. K. Young
C. K. Young

Reputation: 223193

You can use POSIX::mktime to turn broken-up time into a timestamp. Be aware that the month is 0-based, and the year is 1900-based, so adjust accordingly. :-)

use POSIX qw(mktime);
$timestamp = mktime($sec, $min, $hour, $day, $month - 1, $year - 1900);

Upvotes: 1

Related Questions