Re: How to Compute Hours In a Day?

2008-10-19 Thread Dave Rolsky

On Mon, 20 Oct 2008, Eugene van der Pijll wrote:


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.


If you write some failing tests, I might be able to fix it.


-dave

/*
http://VegGuide.org   http://blog.urth.org
Your guide to all that's veg  House Absolute(ly Pointless)
*/


Re: How to Compute Hours In a Day?

2008-10-19 Thread Eugene van der Pijll
[EMAIL PROTECTED] schreef:
> I want to iterate the time zones of the world to generate a report of
> all days that aren't exactly 24 hours. I want to handle
> America/Caracas and America/Sao_Paulo correctly. You mentioned
> 2007-12-09 was 24.5 hours long in Venezuela. This is precisely the
> kind of outliers I'm after.

If you want to handle the Sao Paulo situation correctly, measure the
intervals between two middays (12:00), instead of between midnights (0:00).

It should show the same non-24 hour days, except when there are two DST
changes in one day. Which is unlikely, but not impossible, given that
DST is defined by politicians.

Eugene


Re: How to Compute Hours In a Day?

2008-10-19 Thread jim . monty
Zefram wrote:
>[EMAIL PROTECTED] wrote:
> >How do I compute the number of hours in a day in a specific time zone?
> 
> Try this:

Thanks for the working example. It's helpful.

> 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.)
>
> Beware that the above code assumes that
> midnight exists every day.  We recently had a thread
>  about
> midnight not existing in some timezones, specifically America/Sao_Paulo.

It's funny you should mention that thread. It's what inspired my little 
exercise, which I thought was going to be easier than it is. Here's what I 
*really* want to do:

I want to iterate the time zones of the world to generate a report of all days 
that aren't exactly 24 hours. I want to handle America/Caracas and 
America/Sao_Paulo correctly. You mentioned 2007-12-09 was 24.5 hours long in 
Venezuela. This is precisely the kind of outliers I'm after.

So I'm looking for the best, most canonical, most 
true-to-the-spirit-of-DateTime way to accomplish this using, presumably, 
DateTime::Duration and possibly DateTime::Format::Duration.

Jim Monty



Re: How to Compute Hours In a Day?

2008-10-19 Thread Eugene van der Pijll
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


Re: How to Compute Hours In a Day?

2008-10-19 Thread Zefram
[EMAIL PROTECTED] wrote:
>How do I compute the number of hours in a day in a specific time zone?

Try this:

use DateTime;
for(my $today = DateTime->new(year=>2007, time_zone=>$ARGV[0]); $today->year == 
2007; ) {
(my $tomorrow = $today->clone)->add(days=>1);
print $today, "  ", ($tomorrow->epoch - $today->epoch)/3600, "\n";
$today = $tomorrow;
}

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.)

Beware that the above code assumes that
midnight exists every day.  We recently had a thread
 about
midnight not existing in some timezones, specifically America/Sao_Paulo.

-zefram


How to Compute Hours In a Day?

2008-10-19 Thread jim . monty
How do I compute the number of hours in a day in a specific time zone?
 
Let's say I want to iterate the days of the year from Jan 1 thru Dec 31
and print the number of hours in each day in the America/New_York time
zone. I expect 363 days to have 24 hours, one day to have 23 hours, and
one day to have 25 hours. I want to know how best to compute these
numbers of hours in each day.
 
Jim Monty