amprantino
amprantino

Reputation: 1687

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?

Upvotes: 3

Views: 25966

Answers (2)

AnFi
AnFi

Reputation: 10913

You have missed requesting localtime to produce scalar (string) instead of array.

use Date::Parse;
my $current = str2time (scalar(localtime(time)));
print $current, "\n";
print scalar(localtime($current)),"\n";

perldoc -f localtime

Converts a time as returned by the time function to a 9-element list with the time analyzed for the local time zone. Typically used as follows:
# 0 1 2 3 4 5 6 7 8
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
...
In scalar context, "localtime()" returns the ctime(3) value:
$now_string = localtime; # e.g., "Thu Oct 13 04:54:34 1994"

Upvotes: 3

Sobrique
Sobrique

Reputation: 53508

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.

Upvotes: 9

Related Questions