Chas. Owens
Chas. Owens

Reputation: 64939

How do I determine the current timezone a machine is set to with Perl?

I had assumed it would be as simple as $ENV{TZ}, but the TZ environment variable is not set, and yet the date command still knows I am in EDT, so there must be some other way of determining timezone (other than saying chomp(my $tz = qx/date +%Z/);).

Upvotes: 9

Views: 10568

Answers (6)

Vince Pelss
Vince Pelss

Reputation: 1

Use: returns server time zone offset from UTC in hours. This builds on the above examples and will work with DST

 my $hour_seconds = 60 * 60;
 my $day_seconds = 24 * $hour_seconds;
 #what is today's time at 00:00
 my $right_now = time();
 my $days = $right_now / $day_seconds;
 my $years = $right_now / ($day_seconds * 365);
 my $days_rounded = sprintf("%d", $days);
 my $today_seconds_at_midnight = $days_rounded  * $day_seconds;
 
 my @lt = localtime($today_seconds_at_midnight + ($day_seconds / 2)); #must use noon today or we will get odd values
 my $tz = $lt[2] - 12; #calc timezome difference, includes DST
 

Upvotes: -1

sancho21
sancho21

Reputation: 3653

If you just need something like +05:30 (UTC+5.5/India time), you may use the following code.

my @lt = localtime();
my @gt = gmtime();

my $hour_diff = $lt[2] - $gt[2];
my $min_diff  = $lt[1] - $gt[1];

my $total_diff = $hour_diff * 60 + $min_diff;
my $hour = int($total_diff / 60);
my $min = abs($total_diff - $hour * 60);

print sprintf("%+03d:%02d", $hour, $min);

This answer is inspired by Pavel's answer above.

Upvotes: 3

Pavel
Pavel

Reputation: 19

Maybe this faster:

my @lt = localtime(12*60*60);
my @gt = gmtime(12*60*60);
$tz = @lt[2] - @gt[2];
$tz_ = sprintf("%+03d:00", $tz); # for +02:00 format

Upvotes: 1

Dave Rolsky
Dave Rolsky

Reputation: 4532

If you want something more portable than POSIX (but probably much slower) you can use DateTime::TimeZone for this:

use DateTime::TimeZone;

print DateTime::TimeZone->new( name => 'local' )->name();

Upvotes: 7

Beano
Beano

Reputation: 7861

use POSIX;
localtime();
my ($std, $dst) = POSIX::tzname();

tzname() gives you access to the POSIX global tzname - but you need to have called localtime() for it to be set in the first place.

Upvotes: 6

Igor Krivokon
Igor Krivokon

Reputation: 10275

use POSIX;
print strftime("%Z", localtime()), "\n";

Upvotes: 15

Related Questions