Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

How to get TZ difference?

by dda (Friar)
on Jun 28, 2003 at 10:37 UTC ( [id://269845] : perlquestion . print w/replies, xml ) Need Help??

dda has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks!

Is it possible to get the difference from GMT in hours? My $ENV{TZ } is not set, however, the following code shows some values:

#!/usr/bin/perl -w use strict; use POSIX; my ($std, $dst) = POSIX::tzname(); print "std: $std\n"; print "dst: $dst\n"; print "TZ: " . ($ENV{TZ} || "Unset") . "\n";
Result is:
on Win32 machine: std: Russian Standard Time dst: Russian Daylight Time TZ: Unset on linux machine: std: GMT dst: GMT TZ: Unset
Where does perl get those values? At he same time, php code:
<?php $stz = date("Z"); echo $stz/60/60; ?>
shows 4..


Replies are listed 'Best First'.
Re: How to get TZ difference?
by adrianh (Chancellor) on Jun 28, 2003 at 10:50 UTC

    Windows boxes - no ideas.

    On Un*x boxes, there are a number of files that can be used to store timezones (/etc/localtime, /etc/timezone, probably some others.)

    If you're playing with timezone code I recommend you take a look at the new DateTime modules - DateTime::TimeZone in particular. Very useful stuff.

Re: How to get TZ difference?
by BrowserUk (Patriarch) on Jun 28, 2003 at 14:09 UTC

    The posix subsytem on win32 falls back to using values from the registry if the TZ environment variable isn't set.

    The key in question is


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller

Re: How to get TZ difference?
by hsweet (Pilgrim) on Jun 28, 2003 at 12:04 UTC
    One way might be to use Perl's localtime and gmtime functions. Something like this should work.
    $local=(localtime)[2]; $gmt=(gmtime)[2]; $diff=$gmtime-$local; #depending on which side of the line you are on

    Time flies like an arrow, fruit flies like banannas

      This doesn't work when localtime and gmtime are on different days (ie, in zone GMT+4 between 8:00pm and 11:59pm). Here's a fixed version:
      #!/usr/bin/perl @local=(localtime); @gmt=(gmtime); $diff=$gmt[2]-$local[2]; if ($gmt[5] > $local[5] || $gmt[7] > $local[7]) { $diff += 24; } elsif ($gmt[5] < $local[5] || $gmt[7] < $local[7]) { $diff -= 24; }
        This is a little shorter and more confusing.
        @local=(localtime(time+$off_h*60*60)); @gmt=(gmtime(time+$off_h*60*60)); $diff=$gmt[2]-$local[2] + ($gmt[5] <=> $local[5] || $gmt[7] <=> $local[7])*24;
        thanks for the correction

        Time flies like an arrow, fruit flies like banannas

        you forgot to compare the months in case when we have last day of the month, around midnight it will return inccorect results