The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.


Tie::TZ - tied $TZ setting %ENV and calling tzset()


 use Tie::TZ qw($TZ);
 $TZ = 'GMT';
   local $TZ = 'EST+10';
   # ...


Tie::TZ provides a tied $TZ variable which gets and sets the TZ environment variable $ENV{'TZ'}. When it changes %ENV, it calls tzset() (see POSIX) if available, ensuring the C library notices the change for subsequent localtime() etc.

    $TZ = 'GMT';
    # does  $ENV{'TZ'}='GMT'; POSIX::tzset();

For a plain set, you can just as easily store and tzset() yourself (or have a function do the combination). The power of a tied variable comes when using local to have a different timezone temporarily. Any goto, return, die, etc, exiting the block will restore the old setting, including a tzset() for it. See examples/ in the sources for complete program.

    { local $TZ = 'GMT';
      print ctime();
      # TZ restored at block exit

    { local $TZ = 'GMT';
      die 'Something';
      # TZ restored when the die unwinds

Storing undef to $TZ deletes $ENV{'TZ'} which unsets the environment variable. This generally means the timezone goes back to the system default (/etc/timezone or wherever).

As an optimization, if a store to $TZ is already what $ENV{'TZ'} contains then POSIX::tzset() is not called. This is helpful if some of the settings you're using might be the same -- just store to $TZ and it notices when there's no change. If you never store anything different from the startup value then the POSIX module is not even loaded.

If tzset() is not implemented on your system then Tie::TZ just sets the environment variable. This is only likely on a very old or very limited C library. Of course setting the environment variable might or might not actually affect the timezone in force (see "Time and Date" in perlport).


On many systems tzset() is not actually needed. Decent C libraries look for a new TZ each time in the various localtime() etc functions. Here are some cases where you do need it,

  • Using Perl-level localtime() in threaded Perl 5.8.8 (whether using threads or not). Normally Perl arranges to call tzset() if the C library doesn't (based on a configure test, see Config). But in 5.8.8 and earlier, Perl didn't do that on localtime_r, and in some versions of GNU C that function needed an explicit tzset().

  • Using localtime() from C code on older systems which don't check for a new TZ each time. Even if Perl's configure test does the right thing for Perl level calls, you may not be so fortunate deep in external libraries.

  • When using the global variables timezone, daylight and tzname, either from C code or from the POSIX module tzname() function.


By default nothing is exported and you can use the full name $Tie::TZ::TZ,

    use Tie::TZ;
    $Tie::TZ::TZ = 'GMT';

Import $TZ in the usual way (see Exporter) to shorten, either by name

    use Tie::TZ '$TZ';
    $TZ = 'GMT';

or ":all" imports everything (there's only $TZ presently)

    use Tie::TZ ':all';
    $TZ = 'GMT';


The Env module can make a tied $TZ in a similar way if you're confident you don't need tzset(). The local trick above works equally well with Env. You can also apply local directly to $ENV{'TZ'}, eg. local $ENV{'TZ'} = 'EST+10', except you can't unset that way. (Attempting to store undef provokes a warning before Perl 5.10 and comes out as the empty string, which might be subtly different to unset.)

When you get sick of the C library timezone handling have a look at DateTime::TimeZone. It's a full copy of the Olson timezone database so is big (no doubt you could turf what you don't use), but it's all Perl and is friendlier for calculations in multiple zones.


POSIX, Env, "Time and Date" in perlport, DateTime::TimeZone



Copyright 2008, 2009, 2010, 2011, 2019, 2020 Kevin Ryde

Tie-TZ is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.

Tie-TZ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with Tie-TZ. If not, see <>.