1

I have the server where system timezone is EST

It was set with

# timedatectl set-timezone EST
# timedatectl 
  Local time: Tue 2019-06-18 03:29:42 EST
  Universal time: Tue 2019-06-18 08:29:42 UTC
    RTC time: Tue 2019-06-18 08:29:42
    Time zone: EST (EST, -0500)
    NTP enabled: yes
    NTP synchronized: no
    RTC in local TZ: no
    DST active: n/a

Then in my perl code i try to detect timezone and convert time to UTC And for some reason, a timezone is detected as EDT. Currently (summer) EST is one our after EDT

My perl code is

# cat test.cgi # code file is named test.cgi
#!/usr/bin/perl -w

use Date::Manip;

print "Local time: ".UnixDate("now","%Y-%m-%d %H:%M:%S %Z")."\n";

# get local system timezone
my $TZ = UnixDate("now","%Z");

# convert time to GMT 
my $dtlocal =  Date_ConvTZ(ParseDate(UnixDate("now","%g")),$TZ,"GMT");

# format GMT time
my $dt =  UnixDate($dtlocal,"%Y-%m-%d %H:%M:%S"); 

print "Timezone: $TZ\n";
print "UTC time: $dt\n";

And i execute the script

# date
Tue Jun 18 04:17:56 EST 2019
# date -u
Tue Jun 18 09:17:58 UTC 2019
# ./test.cgi 
Local time: 2019-06-18 04:18:00 EDT
Timezone: EDT
UTC time: 2019-06-18 08:18:00

What can be the reason that Date::Manip detects timezone wrongly? Is there other good way to detect system timezone?

UPDATE.

I have just found that POSIX detects timezone correctly. So, the problem is with Date::Manip

 use POSIX;
 print strftime("%Z", localtime()), "\n";
Roman Gelembjuk
  • 1,797
  • 2
  • 25
  • 50
  • I wasn't quickly able to find where exactly Date::Manip makes its decision of whether you're on standard time or DST, but the US changed its start/end dates for DST in 2007. Is it possible that your Date::Manip might be old enough to still be using the old start/end dates instead of the current ones? – Dave Sherohman Jun 18 '19 at 09:30
  • I have the version 6.54 , according to their docs it is from 2016-05-31 . https://metacpan.org/changes/distribution/Date-Manip – Roman Gelembjuk Jun 18 '19 at 09:39
  • 1
    I've run your code using the latest version of Date::Manip (6.77) and I'm still seeing the same, incorrect, behaviour. I suggest [reporting it as a bug](https://rt.cpan.org/Public/Dist/Display.html?Name=Date-Manip). – Dave Cross Jun 18 '19 at 10:02
  • It's important to remember that EST and EDT are not fully realized time zones. They are offsets. The time zone is America/New_York (or the appropriate locale). This is how you can have a winter datetime and a summer datetime in the same timezone with a different offset. So the "decision" whether DST is in effect depends on both the timezone and the datetime in question. – Grinnz Jun 18 '19 at 14:49
  • Therefore it sounds like Date::Manip is trying to be too clever, and assuming that all EST time zones are America/New_York. – Grinnz Jun 18 '19 at 14:53

2 Answers2

2

One way to find the time zone is with DateTime::TimeZone. Used with DateTime for other needs

use warnings;
use strict;
use feature 'say';

use DateTime; 
use DateTime::TimeZone; 

my $tz = DateTime::TimeZone->new(name => "local");
say $tz->name();                                   #--> America/Los_Angeles


my $dt = DateTime->now(time_zone => "local");
say "local: $dt";                             #--> local: 2019-06-18T09:57:58

$dt->set_time_zone("UTC"); 
say "UTC: $dt";                               #--> UTC: 2019-06-18T16:57:58

Please see documentation for details, at least for the DateTime::TimeZone constructor.

Also note their recommendation to not use "short" names ("EST"), under $tz->short_name...


Once you are working with DateTime can also have offset

my $dt = DateTime->now(time_zone => 'local');

say $dt->offset/(60*60);                       #--> -7

say $dt->strftime("%z");                       #--> -0700

The method offset returns the time-zone offset in seconds.

The strftime offer formats we normally expect; docs say "any deviation from the POSIX standard is probably a bug." A full timestamp example: $dt->strftime('%Y-%m-%dT%H:%M:%S%z').

zdim
  • 64,580
  • 5
  • 52
  • 81
2

The Date::Manip::TZ documentation has a section on Determining the System Time Zone. If you scroll down a bit, you will find a list of which methods are used (and in what order) to determine the system time zone, depending on whether you're running under Unix or Windows.

Based on what you've posted in the question, it appears to be reading the local time correctly, but failing to identify the right time zone, so you should be able to find the root problem by going down the list of TZ identification methods used on your OS. (i.e., for Unix, check $::TZ, then the zone and TZ environment settings, then /etc/TIMEZONE, etc. until you find one that both exists and has the wrong timezone listed)

Dave Sherohman
  • 45,363
  • 14
  • 64
  • 102