Re: How to Compute Hours In a Day?

[email protected] (Eugene van der Pijll)
Newsgroups perl.datetime
Message-ID <[email protected]>
Zefram schreef:
> It ought to be possible to do the interval calculation using
> DateTime::Duration instead of ->epoch, but the behaviour of DT::D is
> unreasonably confusing and I couldn't get it to work.  (Strangely, I got
> a version that worked fine for America/New_York, where all the days are
> integer numbers of hours, but lost the fractional hour of 2007-12-09 in
> America/Caracas, which was 24.5 hours long.)

DateTime cannot handle fractional leap hours.

See the source code of subtract_datetime(), section "This is a gross
hack", where the length of the leap hour is hardcoded in the lines

    $bigger_min -= 60
    $bigger_min += 60

This should probably be changed, but datetime math is scary.

As a workaround, convert the time to UTC. (This does not work in all
cases, but for this purpose, it does.

use DateTime;

for my $doy (340..345) {

    # The default time is 00:00:00
    my $day = DateTime->from_day_of_year(
                                year => 2007, day_of_year => $doy,
                                time_zone => 'America/Caracas') or die;

    # To find the end of the day, add 1 day to get 00:00:00 tomorrow
    my $end_of_day = $day->clone->add( days => 1 );

    # Workaround for Venezuela.
    $day->set_time_zone('UTC');
    $end_of_day->set_time_zone('UTC');

    # Standard subtraction would result in a duration of 1 day, so we
    # use delta_ms() which results in a duration without the "days"
    # component. It is expressed entirely in minutes, which can be
    # converted to hours.
    my $hours = $end_of_day->delta_ms($day)->delta_minutes / 60;

    print $day, " has $hours hours.\n";
}


Eugene
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.