diff --git a/FAQ.md b/FAQ.md index 64511be..0666750 100644 --- a/FAQ.md +++ b/FAQ.md @@ -1,5 +1,6 @@ ##Contents - [Why can't I do day arithmetic on a `year_month_day`?](#day_arithmetic) +- [Why is `local_t` not a proper clock?](#local_t) *** @@ -55,4 +56,40 @@ This philosophy is similar to that which we have for containers: It would be su It would be very easy to add `T& list::operator[](size_t index)`. But that would encourage the programmer to use `list` when a random-access container would probably be more appropriate for the task. -This library continues in that tradition: The expensive operations are not hidden. \ No newline at end of file +This library continues in that tradition: The expensive operations are not hidden. + + +### Why is `local_t` not a proper clock? + +`local_time` is a `time_point`, where `local_t` is just an empty `struct`. Every other `time_point` has a proper clock with (`now()`) for that template parameter. Why is `local_time` special this way, and won't this make generic programming with `time_point`s harder? + +This was done because `local_time` _is_ different from all other `time_point`s. It has no associated timezone. Thus it has no epoch. A `local_time` could be paired with _any_ timezone. For example: + + auto tp = local_days{nov/6/2016} + 7h; + +This represents Nov. 6, 2016 07:00:00 in _any_ timezone. To make this time_point concrete, you have to pair it with a specific timezone: + + auto zt = make_zoned("America/New_York", tp); + +Now `zt` represents Nov. 6, 2016 07:00:00 in New York. We could have just as easily paired it with any other timezone, including `current_zone()`. + +Now imagine if `local_time` had an associated clock with which you could call `now()`: What would this code mean? + + std::this_thread::sleep_until(tp); + +This would be a logic error because it is _ambiguous_ what time to sleep until. As specified, with `local_t` being an empty `struct`, the above line of code (a logic error) does not compile: + + error: no member named 'now' in 'date::local_t' + while (_Clock::now() < __t) + ~~~~~~~~^ + note: in instantiation of function template specialization + 'std::this_thread::sleep_until>' requested here + std::this_thread::sleep_until(tp); + +So this is yet another example of errors being detected at compile time, rather than letting them happen at run time. + +The proper way to do this is to pair `tp` with some timezone creating a `zoned_time` (`zt` above), and then saying: + + std::this_thread::sleep_until(zt.get_sys_time()); + +This compiles and will do exactly what it looks like it does: Sleeps until Nov. 6, 2016 07:00:00 in New York. This works correctly even if there is a daylight saving transition between the time the `sleep_until` is called, and the time to wake up (currently such a transition is scheduled 6 hours earlier than the wakeup time). It works because all `sleep_until` has to worry about is the `sys_time` (`time_point`) it was handed, and that `sys_time` has been correctly mapped from "America/New_York". \ No newline at end of file