-
-
Notifications
You must be signed in to change notification settings - Fork 25
offset_for_local_datetime: Add a 'ignore_missing_spans' argument #26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -193,7 +193,7 @@ sub offset_for_datetime { | |
sub offset_for_local_datetime { | ||
my $self = shift; | ||
|
||
my $span = $self->_span_for_datetime( 'local', $_[0] ); | ||
my $span = $self->_span_for_datetime( 'local', $_[0], $_[1] ); | ||
|
||
return $span->[OFFSET]; | ||
} | ||
|
@@ -210,6 +210,7 @@ sub _span_for_datetime { | |
my $self = shift; | ||
my $type = shift; | ||
my $dt = shift; | ||
my $ignore_missing_spans = shift; | ||
|
||
my $method = $type . '_rd_as_seconds'; | ||
|
||
|
@@ -218,7 +219,7 @@ sub _span_for_datetime { | |
my $span; | ||
my $seconds = $dt->$method(); | ||
if ( $seconds < $self->max_span->[$end] ) { | ||
$span = $self->_spans_binary_search( $type, $seconds ); | ||
$span = $self->_spans_binary_search( $type, $seconds, $ignore_missing_spans ); | ||
} | ||
else { | ||
my $until_year = $dt->utc_year + 1; | ||
|
@@ -244,7 +245,7 @@ sub _span_for_datetime { | |
|
||
sub _spans_binary_search { | ||
my $self = shift; | ||
my ( $type, $seconds ) = @_; | ||
my ( $type, $seconds, $ignore_missing_spans ) = @_; | ||
|
||
my ( $start, $end ) = _keys_for_type($type); | ||
|
||
|
@@ -276,7 +277,15 @@ sub _spans_binary_search { | |
|
||
$i += $c; | ||
|
||
return if $i >= $max; | ||
if ($i >= $max) { | ||
# No span found for this time zone? If the user has asked, | ||
# return the previous span so the offset to utc is higher, | ||
# effectively moving the time forward whatever the difference | ||
# in the two spans is (typically 1 hour for DST). | ||
return $self->{spans}[ $i - 1 ] if $ignore_missing_spans; | ||
|
||
return; | ||
} | ||
} | ||
else { | ||
|
||
|
@@ -687,14 +696,18 @@ for the given datetime. This takes into account historical time zone | |
information, as well as Daylight Saving Time. The offset is | ||
determined by looking at the object's UTC Rata Die days and seconds. | ||
|
||
=head2 $tz->offset_for_local_datetime( $dt ) | ||
=head2 $tz->offset_for_local_datetime( $dt, [ $ignore_missing_spans ] ) | ||
|
||
Given a C<DateTime> object, this method returns the offset in seconds | ||
for the given datetime. Unlike the previous method, this method uses | ||
the local time's Rata Die days and seconds. This should only be done | ||
when the corresponding UTC time is not yet known, because local times | ||
can be ambiguous due to Daylight Saving Time rules. | ||
|
||
If C<$ignore_missing_spans> is true and the local time for C<$dt> does not | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if it makes sense to document this talking about "spans". Note that the docs do not mention this term at all, because it's really just an internal detail. I think this might be better presented as
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, we're going to the previous span but that moves the time forward, so I'd add to the above ...
|
||
exist in the time zone (due to DST changes for example), the next span | ||
up will be returned. | ||
|
||
=head2 $tz->is_dst_for_datetime( $dt ) | ||
|
||
Given a C<DateTime> object, this method returns true if the DateTime is | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
use strict; | ||
use warnings; | ||
|
||
use lib 't/lib'; | ||
use T::RequireDateTime; | ||
|
||
use Test::More; | ||
use Test::Fatal; | ||
|
||
use DateTime::TimeZone; | ||
use Try::Tiny; | ||
|
||
my $tz = DateTime::TimeZone->new( name => 'America/Denver' ); | ||
|
||
my $dt = DateTime->new( | ||
year => 2018, | ||
month => 3, | ||
day => 11, | ||
hour => 2, | ||
minute => 0, | ||
second => 0, | ||
time_zone => 'UTC', | ||
); | ||
|
||
{ | ||
my $error; | ||
|
||
try { | ||
my $offset = $tz->offset_for_local_datetime($dt); | ||
} | ||
catch { | ||
$error = $_; | ||
}; | ||
|
||
like( $error, qr/invalid local time/i, 'got correct error' ); | ||
} | ||
|
||
{ | ||
my $offset = $tz->offset_for_local_datetime( $dt, 1 ); | ||
is( $offset, -25200, 'got -7 offset (even though we should be -6)' ); | ||
} | ||
|
||
done_testing(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is
$i - 1
good enough (since $i can be > $max, not just == $max) ...