Search code examples
perldatetimedst

Perl DateTime "is_dst()" method not working correctly


I'm trying to use the is_dst() method in the DateTime module to determine whether a daylight savings transition is occurring.

I started by writing a very basic example that I was sure would work, but for some reason I'm getting unexpected results.


Example:

#!/usr/bin/perl

use strict;
use warnings;
use DateTime;

my $dt1 = DateTime->new(
    'year'  => 2015,
    'month' => 3   ,
    'day'   => 8   ,
    'hour'  => 3   ,
);

my $dt2 = DateTime->new(
    'year'  => 2015,
    'month' => 3   ,
    'day'   => 7   ,
    'hour'  => 3   ,
);

print $dt1."\n";
print $dt2."\n";
print $dt1->is_dst()."\n";
print $dt2->is_dst()."\n";

I started with a date that I knew was a daylight savings transition: Sunday, March 8, 2015. I chose 3 AM because I knew that the daylight savings transition would have already occured at that point in time.

Then I took a date that I knew was before the daylight savings transition: Saturday, March 7, 2015 also at 3 AM.

Then I print the two dates and their corresponding DST flags.

Output:

2015-03-08T03:00:00
2015-03-07T03:00:00
0
0

The two dates print exactly as expected, but for some reason even though the first date occurs during daylight savings time, and the second date occurs before daylight savings time, the DST flag is not set for both of them.

Why is this not working correctly? Am I missing something?


Solution

  • You have to explicitly set the time zone:

    The default time zone for new DateTime objects, except where stated otherwise, is the "floating" time zone...A floating datetime is one which is not anchored to any particular time zone.

    For example:

    use strict;
    use warnings;
    use DateTime;
    
    my $dt1 = DateTime->new(
        'year'      => 2015,
        'month'     => 3,
        'day'       => 8,
        'hour'      => 3,
        'time_zone' => 'America/New_York'
    );
    
    my $dt2 = DateTime->new(
        'year'      => 2015,
        'month'     => 3,
        'day'       => 7,
        'hour'      => 3,
        'time_zone' => 'America/New_York'
    );
    
    print $dt1."\n";
    print $dt2."\n";
    print $dt1->is_dst()."\n";
    print $dt2->is_dst()."\n";
    

    Output:

    2015-03-08T03:00:00
    2015-03-07T03:00:00
    1
    0