Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Converting local time to UTC mystery

by rovf (Priest)
on Sep 05, 2011 at 13:11 UTC ( #924220=perlquestion: print w/ replies, xml ) Need Help??
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>

Comment on Converting local time to UTC mystery
Select or Download Code
Re: Converting local time to UTC mystery
by Anonymous Monk on Sep 05, 2011 at 13:27 UTC

    And what is it that you did you expect?

    $ perl -MHTTP::Date -le " print for ~~localtime, ~~gmtime, str2time(q/ +20110905 142631/) " Mon Sep 5 06:25:26 2011 Mon Sep 5 13:25:26 2011 1315257991 $ perl -MHTTP::Date -le " $f = str2time(q/20110905 142631/) ; print fo +r ~~localtime $f, ~~gmtime $f" Mon Sep 5 14:26:31 2011 Mon Sep 5 21:26:31 2011
    As HTTP::Date promises, when timezone isn't specified, the distance from epoch str2time gives, fed to localtime, produces the original date supplied
      As HTTP::Date promises, when timezone isn't specified, the distance from epoch str2time gives, fed to localtime, produces the original date supplied
      Exactly, and my understanding (and here I probably was wrong) was, that I can supply the optional second parameter to str2time, saying that I don't want to have the result in localtime, but in a different timezone (in my case, 'UTC'). Since this is obviously not the case, what then is the purpose of the second argument to str2time?

      Could you please give me an example, how to call str2time, so that I get the result in UTC?

      -- 
      Ronald Fischer <ynnor@mm.st>
Re: Converting local time to UTC mystery
by Anonymous Monk on Sep 05, 2011 at 13:31 UTC
    With DateTime:
    $ use DateTime::Format::Strptime $ DateTime::Format::Strptime->new(pattern => '%Y%m%d %H%M%S', time_zon +e => '+0200',) $DateTime_Format_Strptime1 = DateTime::Format::Strptime=HASH(0x2ce6490 +); $ DateTime::Format::Strptime->new(pattern => '%Y%m%d %H%M%S', time_zon +e => '+0200',)->parse_datetime('20110905 142631') 2011-09-05T14:26:31 $ DateTime::Format::Strptime->new(pattern => '%Y%m%d %H%M%S', time_zon +e => '+0200',)->parse_datetime('20110905 142631')->epoch 1315225591
      This hard-codes the timezone (+0200). I happen to know that it is two hours off, but in general, the program can run in any local timezone, so I would need to find out how much I am away from UTC.

      In addition, I would strongly prefer a solution which does not involve DateTime. In my case, parsing the string is easy enought that it can be done by HTTP::Date, so the only problem left is the timezone issue.
      So, is there an easy way to find out the time difference? Somehow Perl must already "know" this (otherwise, it would not be able to implement gmtime and localtime correctly, doesn't it?)

      -- 
      Ronald Fischer <ynnor@mm.st>

        I would need to find out how much I am away from UTC.

        ...which changes during the year, making it that much more difficult. Yeah, hardcoding offsets is not the way to go.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://924220]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (8)
As of 2014-12-26 09:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (171 votes), past polls