Updated FAQ (markdown)

Howard Hinnant
2018-05-22 15:35:32 -04:00
parent 9ec105344e
commit 69304b01ec

19
FAQ.md

@@ -3,7 +3,7 @@
- [Why is `%A` failing?](#week_day_parse_bug)
- [Why is `local_t` not a proper clock?](#local_t)
- [Why can't I compare instances of `zoned_time`?](#zoned_time_comparison)
- [Why is `weekday` encoded with [0, 6] as [Sun, Sat] instead of the ISO [1, 7] as [Mon, Sun]?](#weekday_encoding)
- [On the encoding of `weekday`](#weekday_encoding)
***
<a name="day_arithmetic"></a>
@@ -131,7 +131,7 @@ When working with `zoned_time` objects, it seems natural that one should be able
In the case that comparison is required by an application, named functors or lambdas defining the comparison operations should be used.
<a name="weekday_encoding"></a>
### Why is `weekday` encoded with [0, 6] as [Sun, Sat] instead of the ISO [1, 7] as [Mon, Sun]?
### On the encoding of `weekday`?
As this library developed, a decision about `weekday` encoding had to be made. There were two existing competing standards:
@@ -162,13 +162,20 @@ These two characteristics make the encoding of `weekday` much less important, ex
This better support takes two forms: Reducing the importance of the encoding on calendrical algorithms, and better parsing support for the ISO [1, 7] encoding.
But ultimately this library chose the [0, 6] encoding. Why?
But ultimately what encoding did this library chose?
This library was written to enable clients to abandon the ancient C/POSIX `<time.h>` API. However the reality is that clients still often have to interoperate with legacy code that uses the old `<time.h>` API. This old API uses the [0, 6] encoding for the `tm_wday` member of the `struct tm`. It is easier on the client to maintain encoding compatibility with `struct tm` than it is if this library rigidly stuck to the ISO encoding. With this compatibility, filling out the `tm_wday` member of `struct tm` is as easy as:
_Answer:_ Neither.
The `weekday{unsigned wd}` constructor accepts both the C [0, 6] encoding and the ISO [1, 7] encoding. How does it tell the difference? It is really quite simple. The two encodings have the same mapping for all of the days except Sunday. The [0, 6] encoding maps 0 to Sunday and the [1, 7] encoding maps 7 to Sunday. The `weekday{unsigned wd}` constructor accepts both `wd == 0` and `wd == 7` to mean Sunday. And aside from this constructor, `weekday` does not expose what encoding it uses internally. It can store [0, 6] and map 7 to 0 at this constructor, or it can store [1, 7] and map 0 to 7 at this constructor.
This library was written to enable clients to abandon the ancient C/POSIX `<time.h>` API. However the reality is that clients still often have to interoperate with legacy code that uses the old `<time.h>` API. This old API uses the [0, 6] encoding for the `tm_wday` member of the `struct tm`. The `weekday{unsigned wd}` constructor can accept a `tm_wday` directly, and work perfectly fine, even though it is also specified to accept the ISO encoding.
Filling out the `tm_wday` member of `struct tm` with a `weekday` is also easy:
```c++
tm.tm_wday = unsigned{wd};
tm.tm_wday = (wd - Sunday).count();
```
And ease translates to less error-prone code.
Indeed, `tm_wday`'s specification says: "days since Sunday — [0, 6]"
As a demonstration of the lowered importance of weekday encoding in calendrical algorithms, see [how to print a calendar](https://github.com/HowardHinnant/date/wiki/Examples-and-Recipes#calendar) which is configurable on the first day of the week. For example here is how to use this code to make Thursday the first day of the week:
```c++