mirror of
https://github.com/HowardHinnant/date.git
synced 2025-08-03 04:34:26 +02:00
Updated FAQ (markdown)
39
FAQ.md
39
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<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.
|
||||
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".
|
Reference in New Issue
Block a user