Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way to get the UTC offset in Perl?

I need to get the UTC offset of the current time zone in Perl in a cross platform (Windows and various flavors of Unix) way. It should meet this format:

zzzzzz, which represents ±hh:mm in relation to UTC

It looks like I should be able to get it via strftime(), but it doesn't appear to be consistent.

Unix:

Input: perl -MPOSIX -e "print strftime(\"%z\", localtime());"
Output: -0700

Windows:

Input: perl -MPOSIX -e "print strftime(\"%z\", localtime());"
Output: Mountain Standard Time

While it appears that Unix is giving me what I want (or at least something close), Windows is not. I'm pretty sure I can do it with Date::Time or similar, but I'd really like to not have any dependencies that I can't guarantee a user will have due to our wide install base.

Am I missing something obvious here? Thanks in advance.

like image 895
Morinar Avatar asked Jan 26 '10 23:01

Morinar


2 Answers

Here is a portable solution using only the core POSIX module:

perl -MPOSIX -e 'my $tz = (localtime time)[8] * 60 - mktime(gmtime 0) / 60; printf "%+03d:%02d\n", $tz / 60, abs($tz) % 60;'

Bonus: The following subroutine will return a full timestamp with time zone offset and microseconds, as in "YYYY-MM-DD HH:MM:SS.nnnnnn [+-]HHMM":

use POSIX qw[mktime strftime];
use Time::HiRes qw[gettimeofday];

sub timestamp () {
  my @now = gettimeofday;
  my $tz  = (localtime $now[0])[8] * 60 - mktime(gmtime 0) / 60;
  my $ts  = strftime("%Y-%m-%d %H:%M:%S", localtime $now[0]);
  return sprintf "%s.%06d %+03d%02d", $ts, $now[1], $tz / 60, abs($tz) % 60;
}
like image 111
Deven T. Corzine Avatar answered Nov 15 '22 14:11

Deven T. Corzine


Time::Local should do the trick

use Time::Local;
@t = localtime(time);
$gmt_offset_in_seconds = timegm(@t) - timelocal(@t);
like image 43
mob Avatar answered Nov 15 '22 15:11

mob