in reply to Timezone Conversion

Howdy there, and welcome to the Monastery!

There's any number of modules for parsing dates/times on CPAN - Time::ParseDate comes to mind -, and once you've parsed a time, converting it to UTC is easy. That said, maybe I'm missing the obvious, but how do you expect to succeed when you don't know the time zone? 5pm Mountain isn't the same as 5pm Eastern, and if you're only told something happened at "5pm" without a timezone, you cannot say when it actually happened.

That said, your example - "11:50:45.242 EDT OCT 27 2015" - gives a time zone, EDT (Eastern Daylight Time). Are you able to rely on that being correct? Because if so, the problem's fairly trivial again.

Replies are listed 'Best First'.
Re^2: Timezone Conversion
by choroba (Cardinal) on Oct 27, 2015 at 22:46 UTC
    once you've done parsed(sic!) a time, converting it to UTC is easy

    It is:

    #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; use Time::ParseDate; use Time::Piece; my $string = '11:50:45.242 EDT OCT 27 2015'; my $sec = parsedate($string); my $tp = do { local $ENV{TZ} = 'UTC'; localtime $sec }; my ($microsec) = $string =~ /\.([0-9]+)/; # Microseconds not handled +by the modules. say $tp->strftime("%Y-%m-%d %H:%M:%S.$microsec");

    Note, however, that EDT is ambiguous, and you can get various strange results from times when Eastern Daylight Time is not observed. Timezone names like America/New_York should be preferred.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      Time zone conversion. Fun stuff. Looks easy until you get into it.

      It's not the math that kills you; it's the human complexity element. There's a reason the Time Zone Database is so large.

      If the timezone is given to you as EDT then you're stuck doing your best to avoid or translate ambiguity with what you're given.

      I seem to recall the two keys to doing graceful time conversions are knowing what rules are followed in the creation of the timestamp format you are receiving, and knowing what timezone the target should be.

      I did a time conversion routine at one point where I insisted I should be able to perform the translation in a single computation (and, frankly, I still argue that I should have been able to), but kept wrapping myself around the axle in handling the odd cases. Probably just wasn't my best head-in-the-algorithm day, but the troubles it kept causing me highlighted what I probably should have done from the start

      I finally surrendered and made it a two-step process; convert source time to UTC, then convert UTC to target timezone.

      Not only did I get it right without hassle, but the code was astoundingly easier to read and maintain for the poor sucker who had to work on it the next time they changed the DST rules.

      I begrudgingly accepted the increased computation cost of two conversions for code that was easier to read and maintain.

        I begrudgingly accepted the increased computation cost of two conversions for code that was easier to read and maintain.
        I have found over time that I normalize input (in this case local TZ => UTC), and regionalize output (UTC => local TZ) -- all data inside of the system is in normalized form. Needing to deal with only one TZ internally to the system is much easier than dealing with unnormalized data anywhere it is encountered.

        --MidLifeXis

        The last time DST rules were changed, I had to figure out a way to automate 350 Cisco and Juniper routers (globally) to update so they'd log properly. This change required many devices to have their firmware updated. It was a nightmare for which I wish I still had that code.

      Hi choroba, thank you for your response. I tried your code and don't seem to get the conversion to UTC when say executes. I get "2015-10-27 11:50:45.242" not "2015-10-27 15:50:45.242" that I expect, I'm not sure if this is because the code is running on a machine where local timezone is EDT / NewYork or if somehow I've botched your example. Any thoughts?

        What OS, what Perl version? It works for me (both Linux and cygwin, 5.18 / 5.22). Also, check the versions of the used modules.
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ