On Fri, Dec 27, 2013 at 1:48 PM, Zefram <zef...@fysh.org> wrote:

> Eric Brine wrote:
> >Given a date and time zone, is it possible to obtain the first time of
> that
> >date?
>
> Given standard APIs for time conversion, I'd perform a binary search
> among UT times, converting them to the zone's local time and looking
> for the threshold at which the local date changes.  The result of the
> conversion at the threshold time includes a local time-of-day that should
> be the one you're after.
>

I posted a solution here:
http://stackoverflow.com/a/20850899/589924

I perform a binary search of the tz's spans, looking at the *local* times.

If a span is found (i.e. if midnight does exist locally), I convert the
local time to a UTC time using the offset of the earliest matching span.
(The latest span is usually used.)

If a span isn't found (i.e. if midnight does not exist locally), I use the
UTC start time of the following span.

*I made one assumption*: There is no dt to which one can add time to obtain
a dt with an earlier date.

Test:

sub new_date {
    my $y = shift;
    my $m = shift;
    my $d = shift;
    return DateTime->new(
        year => $y, month => $m, day => $d,
        @_,
        hour => 0, minute => 0, second => 0, nanosecond => 0,
        time_zone => 'floating'
    );}

{
    # No midnight.
    my $tz = DateTime::TimeZone->new( name => 'America/Sao_Paulo' );
    my $dt = day_start($tz, new_date(2013, 10, 20));
    print($dt->iso8601(), "\n");     # 2013-10-20T01:00:00
    $dt->subtract( seconds => 1 );
    print($dt->iso8601(), "\n");     # 2013-10-19T23:59:59}
{
    # Two midnights.
    my $tz = DateTime::TimeZone->new( name => 'America/Havana' );
    my $dt = day_start($tz, new_date(2013, 11, 3));
    print($dt->iso8601(), "\n");     # 2013-11-03T00:00:00
    $dt->subtract( seconds => 1 );
    print($dt->iso8601(), "\n");     # 2013-11-02T23:59:59}

I intend to write a brute force tester.



Another type of edge case also might matter, depending on what you
> mean by "the first time of that date". If you actually want the local
> time-of-day at the beginning of the calendar day, that's fine.
>

The dt from which nothing can be subtracted to obtain a dt with the same
date.


> But if iyou actually want the lowest local time-of-day that occurs at any
> time
> during the calendar day, you could in principle be misled by a zone that
> jumps forward at midnight and then back slightly later (say, forward an
> hour at local 00:00->01:00, then back an hour at local 01:30->00:30).
> I think this also doesn't occur anywhere in the database.
>

I'd want the first 01:00, and my solution would get it.

- Eric

Reply via email to