Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl convert localtime to unix (epoch) time

using perl, I am trying to estimate the time since a file was created. I would like to convert the local time to unix time (epoch), then take unix time of the file & subtract.

The problem I face is that when I convert localtime to unixtime , it is converted incorrectly!

my $current = str2time (localtime(time));
print $current;

The results I get are

2768504400 = Sun, 23 Sep 2057 21:00:00 GMT
2421349200 = Sun, 23 Sep 2046 21:00:00 GMT

Do I have to feed str2time with a specific date format?

like image 862
amprantino Avatar asked Sep 17 '25 10:09

amprantino


1 Answers

You're doing something bizarre here - localtime(time) takes - the epoch time (time) and converts it to a string.

And then you convert it back.

Just use time()

Or perhaps better yet -M which tells you how long ago a file was modified. (In days, so you'll have to multiply up).

e.g.:

my $filename = "sample.csv";
my $modification = -M $filename;
print $modification * 84600;

But if you really want to take the time and convert it back again - you'll need to look at how localtime(time) returns the result.

If you do:

print localtime(time);

You get:

5671624811542661

Because localtime is being evaluated in a list context, and so returning an array of values. (Which you can use without needing to parse).

 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
                                                localtime(time);

If you do it in a scalar context, it returns a string denoting the time:

print "".localtime(time);

Gives:

Thu Sep 24 16:09:33 2015

But note - that might vary somewhat depending on your current locale. That's probably why str2time is doing odd things - because it makes certain assumptions about formats that don't always apply. The big gotcha is this:

When both the month and the date are specified in the date as numbers they are always parsed assuming that the month number comes before the date. This is the usual format used in American dates.

You would probably be better off instead using Time::Piece and strftime to get a fixed format:

e.g.

use Time::Piece;
print localtime(time) -> strftime ( "%Y-%m-%d %H:%M:%S" );

Note - Time::Piece overloads localtime so you can actually use it (fairly) transparently. Of course, then you can also do:

print localtime(time) -> epoch;

And do without all the fuss of converting back and forth.

like image 200
Sobrique Avatar answered Sep 20 '25 23:09

Sobrique