2002-Oct-27 01:59:59 //last dst time|
2002-Oct-27 00:00:00 + 06:00:00 --> 2002-Oct-27 05:00:00 //what?
The reason for this is that the DST boundary for much of the United States is at 2002-Oct-27 02:00:00. If we had a self-adjusting civil clock the on-the-hour times for this date would be as follows:
2002-Oct-27 00:00:00 2002-Oct-27 01:00:00 2002-Oct-27 01:59:59 //last dst time 2002-Oct-27 01:00:00 //adjusted back 2002-Oct-27 02:00:00 2002-Oct-27 03:00:00 2002-Oct-27 04:00:00 2002-Oct-27 05:00:00
One basic problem with adjusting for local times is the labeling problem. Is 2002-Oct-07 01:10:00 before or after the DST boundary? There just isn't any way to disambiguate without some sort of addtional information such as the label DST. In addition, apparently strange pheonomenon w.r.t time occur. For example, durations become strange:
2002-Oct-07 01:59:59 + 00:00:01 --> 2002-Oct-27 01:00:00 //odd that an add 1 second causes a duration of - 00:59:59?
Now lets look at the adjustment at the other DST boundary.
2002-Apr-07 00:00:00 + 06:00:00 --> 2002-Apr-07 07:00:00 //what?
The hourly clock readings on our auto adjusting clock go as follows:
2002-Apr-07 00:00:00 2002-Apr-07 01:00:00 2002-Apr-07 01:59:59 //last non-dst time 2002-Apr-07 03:00:00 //adjusted forward 2002-Apr-07 04:00:00 2002-Apr-07 05:00:00 2002-Apr-07 06:00:00 2002-Apr-07 07:00:00
So in this case the time 2002-Apr-07 02:30:00 turns out to not exist. And, of course there is the apparent duration anomoly.
2002-Apr-07 01:59:59 + 00:00:01 --> 2002-Apr-07 03:00:00 //odd that an add 1 second causes a duration of 01:00:01?
So how can we handle these anomolies. One approach is to use the same approach as used for converting times across time zones. That is, convert the local time to Universal Time, perform the calculations and then convert back. This would look something like the following:
//Internally time converts to UTC time start(date(2002,Apr,07), time_duration(00,00,00), time_zone("ET")); //ET is US Eastern zone -- DST adjusted time end_UT = start + time_duration(6,0,0); time local_end = end_UT.adjust(time_zone("ET"));
In this implementation, the time class does not perform any internal adjustments or remember the timezones. Rather the time_zone class provides the correct adjustment given the time context.
An alternate approach would be to build a class that in remembers the timezones and performs appropriate adjustments. This could be done in a couple ways. A compile-time solution could allow for a timezone policy template that internally defines the timezone handling. The user could then create a new time type that would automatically handle the timezone rules. The user code would then be as follows:
//Internally stores 'Eastern Time' with no adjustments eastern_time start(date(2002,Apr,07), time_duration(00,00,00)); //no TZ spec required eastern_time end = local_end + time_duration(6,0,0); //timezone adjustment handled here.
This has some appeal because it simplifies the programmer's job, increases performance and reduces the required storage for processing large numbers of local times. The operator+ on the eastern_time defers the calculation to the timezone policy implementation class for eastern_time that implements the DST rules. In addition, this local time class can resolve the labeling issue by offering a constructor that allows for disambibuation of the repeated times:
//Internally stores 'Eastern Time' with no adjustments eastern_time start(date(2002,Oct,27), time_duration(01,00,00), DST); //before the DST boundary eastern_time start(date(2002,Oct,27), time_duration(01,00,00), NODST); //after the DST boundary