Updated FAQ (markdown)

Howard Hinnant
2016-06-21 11:02:19 -04:00
parent 8b9d767963
commit 00e71dd650

37
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)
***
@@ -56,3 +57,39 @@ This philosophy is similar to that which we have for containers: It would be su
It would be very easy to add `T& list<T>::operator[](size_t index)`. But that would encourage the programmer to use `list<T>` 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.
<a name="local_t"></a>
### Why is `local_t` not a proper clock?
`local_time` is a `time_point<local_t, Duration>`, 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<date::local_t, std::chrono::hours>>' 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<system_clock, Duration>`) it was handed, and that `sys_time` has been correctly mapped from "America/New_York".