Version 1.1 of acs/ac-00288.txt

Unformatted version of acs/ac-00288.txt version 1.1
Other versions for file acs/ac-00288.txt

!standard 9.6.1(4/2)          17-04-06 AC95-00288/00
!standard 9.6.1(6/2)
!class confirmation 17-04-06
!status received no action 17-04-06
!status received 17-02-18
!subject Providing an indication of when daylight savings begins/ends
!summary
!appendix

From: Tucker Taft
Sent: Saturday, February 18, 2017  3:00 PM

We have a customer who is worrying about what happens when they have a user
requesting some job to be started, at say, 2:30AM, and it turns out to be the
night when daylight savings begins or ends.  It seems like it might be worth
augmenting the Time_Zones.UTC_Time_Offset interface with a way to know whether
it is the morning when daylight savings time begins or ends.  Here are a couple
of interfaces that Microsoft provides related to this:

   TimeZoneInfo.IsAmbiguousTime:
   https://msdn.microsoft.com/en-us/library/bb396403(v=vs.110).aspx

   TimeZoneInfo.GetAmbiguousTimeOffsets:
   https://msdn.microsoft.com/en-us/library/bb382127(v=vs.110).aspx

***************************************************************

From: Randy Brukardt
Sent: Saturday, February 18, 2017  6:35 PM

You can detect that with the existing interfaces (assuming, of course, that
they're implemented properly). The trick is to check if the Time_Offset is
different for two nearby times that should be on different sides of the change.

Something like the following should work:

    function Time_Change_Tonight return Boolean is
       -- Returns True if a time zone change will happen
       -- tonight (after midnight!)
       TZ_at_1am : Time_Offset;
       TZ_at_4am : Time_Offset;
       Now : Time := Ada.Calendar.Clock;
       Next_1am : Time;
    begin
       declare
          Year : Year_Number;
          Month : Month_Number;
          Day : Day_Number;
          Seconds : Day_Duration;
       begin
          Split (Now, Year, Month, Day, Seconds);
          if Seconds < 7200.0 then
             Next_1am := Time_of (Year, Month, Day, 3600.0); -- 1am.
          else
             Next_1am := Time_of (Year, Month, Day, 3600.0) + 86400.0; -- 1am tomorrow.
          end if;
        end;
        TZ_at_1am := UTC_Time_Offset (Next_1am);
        TZ_at_4am := UTC_Time_Offset (Next_1am + (3600.0*3));
        return TZ_at_1am /= TZ_at_4am;
    end Time_Change_Tonight;

You can also use a pattern like this to determine the direction of change.
(Such a pattern might not be accurate for times in the distant past or far in
the future, but it should be fine for times that are near the current one.)

This pattern will definitely work with the Janus/Ada implementation (can't speak
for other compilers, of course).

Thus, I don't find much need to add interfaces to the Standard (requiring
everyone to implement them). They might be a bit more convinient, but the need
doesn't seem that common.

***************************************************************

From: Tucker Taft
Sent: Sunday, February 19, 2017  9:48 AM

> You can also use a pattern like this to determine the direction of change.
> (Such a pattern might not be accurate for times in the distant past or
> far in the future, but it should be fine for times that are near the
> current
> one.)

Yes, I recommended something pretty similar.  But it would seem easy enough to
have something that would identify the day and time of start/end of daylight
savings.

> This pattern will definitely work with the Janus/Ada implementation
> (can't speak for other compilers, of course).
>
> Thus, I don't find much need to add interfaces to the Standard
> (requiring everyone to implement them). They might be a bit more
> convenient, but the need doesn't seem that common.

I suppose, but it seems silly to hide the information that clearly must be
present in the implementation.

***************************************************************

From: Erhard Ploedereder
Sent: Sunday, February 19, 2017  2:42 PM

> I suppose, but it seems silly to hide the information that clearly
> must be present in the implementation.

but it isn't necessarily. I would expect that Ada.Calendar maps to similar
OS-calendar services which may or may not expose this information. It is a pain
in the ... to retain information about when the switch-overs occur, since they
are different in different countries.

By the way, replace
  Next_1am := Time_of (Year, Month, Day, 3600.0 + 86400.0); by
  Next_1am := Time_of (Year, Month, Day, 3600.0) + 86400.0; in Randy's code.

[Editor's note: The correction was made in the example above, in case someone
wanted to run it and didn't read the entire thread.]

***************************************************************

From: Tucker Taft
Sent: Monday, February 20, 2017  8:05 AM

>> I suppose, but it seems silly to hide the information that clearly
>> must be present in the implementation.
>
> but it isn't necessarily. I would expect that Ada.Calendar maps to
> similar OS-calendar services which may or may not expose this
> information. It is a pain in the ... to retain information about when
> the switch-overs occur, since they are different in different
> countries. ...

Good point.  I was naively thinking it was in the Ada RTS, but of course it is
in the underlying O/S, and as you point out, the O/S might not expose the needed
information in any portable interface.

***************************************************************

From: Randy Brukardt
Sent: Monday, February 20, 2017  4:49 PM

Just to clarify, that was what I was thinking (even though I didn't explicitly
state it). The information about future time changes is available in the Windows
API, but I don't know if that is true on other targets. And since we didn't need
that information to answer the specific question posed, it seemed better to
avoid making additional requirements on the target. (It would be fairly complex
to answer the question even if that information was available given that there
are two time changes per year -- it wouldn't be appreciably shorter than the
solution I gave. One can imagine other questions that would be easier to answer,
but those probably ought to be left in the "question not asked" territory.)

***************************************************************

Questions? Ask the ACAA Technical Agent