Re: Determining next DST transition

2010-08-04 Thread Elliot Merrony

On 30/07/2010 14:59, Anthony R. J. Ball wrote:

On Fri, Jul 23, 2010 at 04:39:58PM +0100, Elliot Merrony wrote:

Hi all

I filed this bug last week and Dave Rolsky advised me to post here
to explain what I was trying to do:


I created a simple lib to do this, though it really should be made available in 
the main libs. It takes a year or range of years and looks at the internals to 
find the DST transitions for the years in question.

Here it is. (tried to send when you first posted, but I'm having mail server 
issues)

[code]


Many thanks for this Anthony, will give it a go. And apologies for time 
taken to respond, I also have mail/news/connection issues...


Elliot



Re: Determining next DST transition

2010-07-30 Thread Anthony R. J. Ball
On Fri, Jul 23, 2010 at 04:39:58PM +0100, Elliot Merrony wrote:
 Hi all
 
 I filed this bug last week and Dave Rolsky advised me to post here
 to explain what I was trying to do:

I created a simple lib to do this, though it really should be made available in 
the main libs. It takes a year or range of years and looks at the internals to 
find the DST transitions for the years in question.

Here it is. (tried to send when you first posted, but I'm having mail server 
issues)

#!perl
package TZInfo;
use strict;
use DateTime;
use POSIX;
use constant UTC_START   = 0;
use constant UTC_END = 1;
use constant LOCAL_START = 2;
use constant LOCAL_END   = 3;
use constant OFFSET  = 4;
use constant IS_DST  = 5;
use constant SHORT_NAME  = 6;

sub get_dst_lib_info {
{  version  = DateTime::TimeZone::Catalog::Olson   Version(),
   last_updated = ( stat( $INC{'DateTime/TimeZone/Catalog.pm'} ) )[9]
};
}

# call with year or array ref of two years for range and timezone to check.
sub get_dst_changes {
my $year = shift;
my $tz   = shift;
my ($DT,$DT_end);
if(ref $year eq 'ARRAY') {
eval { $DT = DateTime-new( %{$year-[0]}, time_zone = $tz ) };
return if $@;
eval { $DT_end = DateTime-new( %{$year-[1]}, time_zone = $tz ) };
return if $@;
   } else {
eval { $DT = DateTime-new( year = $year, time_zone = $tz ); };
return if $@;
$DT_end = $DT-clone();
$DT_end-add( years = 1 );
}
my $i = 100;
my @out;

while ( $i-- ) {#in case we start looping for some reason
my $span = $DT-{tz}-_span_for_datetime( 'utc', $DT );
my $seconds = $DT-utc_rd_as_seconds();
#if($span-
if($span-[UTC_END] =~ /\+/) {
last;
}
my $change = $span-[UTC_END] - $seconds;
# Find the offset and add it. Now we have a DateTime object AT DST 
change
$DT-add( seconds = $change ); 
my $DT2 = $DT-clone();
$DT-add( seconds = 1 );# One second past allows us to search for 
the next DST change
last unless $DT  $DT_end;
push @out, $DT2;
}
\...@out;
}
1;



Re: Determining next DST transition

2010-07-29 Thread Dave Rolsky

On Fri, 23 Jul 2010, Elliot Merrony wrote:

To start from the beginning, I've been using the DT and DT:TZ modules for a 
world clock and want to add a feature which displays the time, date and 
effect of the next DST transition (if any) for each location.


The modules seem to allow me to do anything I could possibly imagine with 
times and time zones, except this. I realise I could test whether each 
location is on DST for every hour from now until 6 months ahead, but was 
hoping that there was a more elegant way of determining when the transition 
is.


Asking around, I was advised that the _rules attribute of an 
DateTime::TimeZone object returns an array of 
DateTime::TimeZone::OlsonDB::Rule objects which encode the start

and end of DST observances.

However, I'm now understanding from Dave's response to the bug that the 
_rules attribute neither is nor should be used for this purpose.


Any advice welcomed. Please bear in mind I'm a Perl beginner (I'm only using 
it due to the existence of these modules!) so apologies for any 
misunderstanding.


Basically, I think we could have a better API than returning the raw 
rules. Off the top of my head, I think a DateTime::Event module that let 
you ask for the next transition in a set would work well. Of course, that 
might still require opening up some chunk of the DT::TimeZone API, but I 
don't want to expose the raw _rules attribute directly.



-dave

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