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.
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;
}
Time::Local
should do the trick
use Time::Local;
@t = localtime(time);
$gmt_offset_in_seconds = timegm(@t) - timelocal(@t);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With