Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Mod_Perl multiple timezones

by dtr (Scribe)
on Jul 23, 2003 at 17:18 UTC ( [id://277261]=perlquestion: print w/replies, xml ) Need Help??

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

I'm writing a bulletin board type program in mod_perl_2 which will display date-times to users in their own time zone, rather than displaying them in the system time zone as many sites seem to do.

In perl 5.6.1, if you modify the value of $ENV{TZ} before calling localtime, then you get back the time fields for that time zone. Very handy if you've got all your dates in your database in UTC.

In 5.8.0, you have to call POSIX::tzset after updating this variable (many thanks to Chmrr for posting this already).

However, this works beautifully from a script, but not at all from mod_perl_2. Does anyone have any idea why this might be the case???

Replies are listed 'Best First'.
Re: Mod_Perl multiple timezones
by fglock (Vicar) on Jul 24, 2003 at 00:57 UTC

    You might want to try DateTime, it is independent of both $ENV{TZ} and POSIX.
    Please tell us at datetime@perl.org if you get problems with it.

Re: Mod_Perl multiple timezones
by dga (Hermit) on Jul 23, 2003 at 17:56 UTC

    The only thing I can think of off hand is the persistance of the mod_perl. I tried this in perl 5.6.0 and it works fine. Is this similar to what you tried in 5.8? ie set TZ print localtime and set TZ and print localtime again in the same script with a different timezone.

    $ENV{TZ}='CST6CDT'; print scalar(localtime), "\n"; $ENV{TZ}='MST7MDT'; print scalar(localtime), "\n"; __END__ #output Wed Jul 23 12:52:59 2003 Wed Jul 23 11:52:59 2003

      The following script will work beautifully when run from the command line.

      When called as a CGI under mod_perl_2 (1.99.08) it will output identical dates for all the different time zones!

      Is this a known problem???

      #! /opt/perl/bin/perl -w
      
      use strict;
      
      use POSIX;
      
      print
          "Content-type: text/plain\n\n",
          "Time zone stuff\n",
          "***************\n",
          "\n";
      
      my $now = time;
      
      
      $ENV{TZ} = "Europe/London"; POSIX::tzset();
      print "Time in Europe/London is   " . localtime($now) . " +OK\n";
      
      
      $ENV{TZ} = "Europe/Paris"; POSIX::tzset();
      print "Time in Europe/Paris is    " . localtime($now) . " +OK\n";
      
      
      $ENV{TZ} = "America/Chicago"; POSIX::tzset();
      print "Time in America/Chicago is " . localtime($now) . " +OK\n";
      
      
      exit;
      

        I'd guess this has something to do with the lack of any real environment to speak of under mod_perl. I will admit to only being familiar with mod_perl 1, however this does look like a bug of some sort (it works fine under mod_perl 1 using Apache::Registry and perl 5.6.1). To track it down, a few more specifics are needed.

        How do you have mod_perl set up (some bits of your apache config might be useful)? What version of perl is mod_perl using?

        PS -- You say that this is being called "as a CGI under mod_perl," which is a bit of an oxymoron -- either you run programs molasses-slow under CGI, or you're using the accelerated features of mod_perl. You can't be doing both -- from Apache's point of view, either you're going through mod_perl, or through mod_cgi.

        perl -pe '"I lo*`+$^X$\"$]!$/"=~m%(.*)%s;$_=$1;y^`+*^e v^#$&V"+@( NO CARRIER'

      I realize that this thread is older than Perl itself, but it comes up very high in Google, so I thought I'd update.

      The following works perfectly for me in Perl 5.10:

      #!/usr/bin/perl use strict; use warnings; ### US Time Zones #my $time_zone = 'US/Alaska'; #my $time_zone = 'US/Aleutian'; #my $time_zone = 'US/Arizona'; #my $time_zone = 'US/Central'; my $time_zone = 'US/Eastern'; #my $time_zone = 'US/East-Indiana'; #my $time_zone = 'US/Hawaii'; #my $time_zone = 'US/Indiana-Starke'; #my $time_zone = 'US/Michigan'; #my $time_zone = 'US/Mountain'; #my $time_zone = 'US/Samoa'; #my $time_zone = 'US/Pacific'; ### set time zone for Perl to access with localtime ### can be any zone listed in /usr/share/zoneinfo and its subfolders $ENV{TZ} = $time_zone; print "System Time Zone from Perl is $ENV{TZ}\n"; my $timenow = localtime(time); print "Time from System is $timenow\n";

      There was no need to use POSIX::tzset().

      It works well from both the command line and from Apache2.

      -Wes

        One thing you may want to consider - I have been having some problems of my own with mod_perl resulting in my system running out of threads. This has forced me into researching threads in much more depth. One thing I have seen multiple times is that localtime() is not thread safe. While this doesn't seem to explain my issues it might explain yours. You can set the environment all you want, but if another thread comes along the TZ can get set to something else, even while localtime() is running, unless you have done something to lock access during your critical time between setting the TZ and getting a result from localtime().
Re: Mod_Perl multiple timezones
by perrin (Chancellor) on Jul 23, 2003 at 17:22 UTC
    How about showing us some code?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://277261]
Approved by The Mad Hatter
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (3)
As of 2024-12-07 18:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Which IDE have you been most impressed by?













    Results (50 votes). Check out past polls.