http://www.perlmonks.org?node_id=924220

rovf has asked for the wisdom of the Perl Monks concerning the following question:

NODE UPDATED - see at the end

UPDATE: FINALLY SOLVED - see at the very end

I have a local time string in the format "YYYYMMMDD HHMMSS" and would like to convert it into "number of seconds since epoch", and "human-readable UTC". This is the approach I took:

use strict; use warnings; # to avoid purgatory use HTTP::Date qw(str2time); my $timestamp_local="20110905 142631"; my $seconds_since_epoch=str2time($timestamp_local, 'UTC'); print "$seconds_since_epoch\n".gmtime($seconds_since_epoch)."\n";
The output of this program is:
1315232791 Mon Sep 5 14:26:31 2011
Given that I am 2 hours east of UTC, this is not what I expected.

My guess is that either my understanding of str2time is wrong, or that my program doesn't know what time zone it is in.

Of course I'm curious to know what I made wrong, and how to correct it. But maybe we have an X/Y problem here, so let me explain, what I a want to do:

In my Windows application, I need to record the creation time of Windows processes, and creation time of files, and relate them (i.e. put them into a timeline). For the process creation time, I use a Windows utility called wmic, which yields the creation time as a string like the one above - actually, I have to squeeze in the space character between "date" and "time" manually, but basically I get the creation time as *local* time. For the file creation time, I use the stat function. The 10th element yields (on Windows) the time stamp of file creation, in the form of "number of seconds since epoch". In order to be able to compare them, I wanted to convert a local time string into a "time_t" value. The str2time function seems to do this, and I pass the argument string 'UTC' to signal that I want to have the result in UTC time.

UPDATE: At least I see where I misunderstood the documentation. The second parameter of str2time doesn't state the zone to converted to, but the zone to converted from, and in addition, time zone names can only be used, if the Time::Zone module is installed. I could get my example program running, when I wrote the call to str2time like this:

my $seconds_since_epoch=str2time($timestamp_local, '+0200');
However, this solves only half of my problem, because in general, I don't know how many hours I am off Greenwich...

2nd UPDATE: SOLUTION

OK, I finally solved it, though I must admit that I find the solution not elegant, and still feel that there must be an easier way to do it:

use strict; use warnings; # to avoid purgatory use HTTP::Date qw(str2time); use Time::Local qw(timelocal timegm); my $difference_to_utc_in_minutes=(timegm(localtime)-timelocal(localtim +e))/60; my $diff_hours=abs($difference_to_utp_in_minutes)/60; my $diff_mins=abs($difference_to_utp_in_minutes)%60; my $difference_to_utc= ($difference_to_utc_in_minutes >= 0 ? '+' : '-'). sprintf("%02d",$diff_hours). sprintf("%02d",$diff_mins) ; my $timestamp_local="20110905 142631"; my $seconds_since_epoch=str2time($timestamp_local, $difference_to_utc) +; print "$seconds_since_epoch\n".gmtime($seconds_since_epoch)."\n";
This results in the output:
1315225591 Mon Sep 5 12:26:31 2011

-- 
Ronald Fischer <ynnor@mm.st>