Search code examples
perltimestampposixgmt

Converting timestamp to GMT with POSIX


Is it possible to convert a given timestamp to GMT in Perl using the POSIX module? Below is what I've tried, but not sure why the time is so far off...

use POSIX;
my $shipts = "2017-09-23 20:53:00";
my $shiptsgmt = strftime("%Y-%m-%d %R", localtime(str2time($shipts, 'GMT')));
print "$shiptsgmt\n";

The localtime of the server is Pacific time, guess what I'm trying to do is not correct. The above produces 2017-09-23 13:53 and I need 2017-09-24 03:53 time.


Solution

  • The POSIX alone cannot do this, not without help from builtins and a little processing.

    An alternative: Time::Piece is core, and in my experience much quicker than POSIX

    perl -MTime::Piece -wE'
        $d = "2017-09-23 20:53:00"; 
        $t = localtime->strptime($d, "%Y-%m-%d %H:%M:%S");
        $t = gmtime($t->epoch);
        say $t->strftime("%Y-%m-%d %H:%M:%S");
    '
    

    This creates an object and then converts it to GMT using the module's (compatible) replacement for gmtime, returing an object which is also suitably flagged as GMT.

    The strftime is the same but much lighter than the POSIX extension and strptime is from FreeBSD. The module also has many methods to get various parts or representations of the datetime object as a string, along with a few other utilities. See also Time::Seconds.

    The DateTime does all this nicely, via its formatters for parsing and stringification. But it is heavy.


    Note   It is rather easy to end up using this module incorrectly, and this answer did just that before ikegami fixed it. So please be very careful with any uses other than basic. See linked answers

    Note that the answer above does not work in v5.10, apparently due to a then-bug in the module.