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 time
s, but that doe开发者_StackOverflow社区sn'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.
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.
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.
In terms of built-ins these may be helpful:
POSIX
(formktime
andstrftime
)Time::Piece
,Time::Local
andTime::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.
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;
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);
精彩评论