Updated Examples and Recipes (markdown)

Howard Hinnant
2019-03-31 16:57:26 -04:00
parent b8f0698a33
commit 102dc3a2b5

@@ -786,9 +786,9 @@ fifth_friday(date::year y)
constexpr auto nan = 0_y/0/0; constexpr auto nan = 0_y/0/0;
std::array<year_month_day, 5> dates{nan, nan, nan, nan, nan}; std::array<year_month_day, 5> dates{nan, nan, nan, nan, nan};
unsigned n = 0; unsigned n = 0;
for (auto m = jan; true; ++m) for (auto m = January; true; ++m)
{ {
auto d = fri[5]/m/y; auto d = Friday[5]/m/y;
if (d.ok()) if (d.ok())
{ {
dates[n] = year_month_day{d}; dates[n] = year_month_day{d};
@@ -808,7 +808,7 @@ The first job is just to initialize the `array` with a bunch of `year_month_day`
Next I iterate over each month for the year `y`. The first thing to do is construct the 5th Friday for this month/year pair: Next I iterate over each month for the year `y`. The first thing to do is construct the 5th Friday for this month/year pair:
```c++ ```c++
auto d = fri[5]/m/y; auto d = Friday[5]/m/y;
``` ```
Now since not every month has a 5th Friday, this may not result in a valid date. But in this function the proper response to constructing an invalid date _is not_ an assert nor an exception. The _proper_ response is to _ignore_ the date and iterate on to the next month. If it is a valid date, then it pushed on to the result. Now since not every month has a 5th Friday, this may not result in a valid date. But in this function the proper response to constructing an invalid date _is not_ an assert nor an exception. The _proper_ response is to _ignore_ the date and iterate on to the next month. If it is a valid date, then it pushed on to the result.
@@ -868,7 +868,7 @@ next_weekday(date::year_month_day ymd, date::weekday target)
The first thing to do is to convert the `year_month_day` to a `sys_days`. This is done because it is very efficient to find the day of the week of a `sys_days` (count of days), and to do day-oriented arithmetic on that data structure. The first thing to do is to convert the `year_month_day` to a `sys_days`. This is done because it is very efficient to find the day of the week of a `sys_days` (count of days), and to do day-oriented arithmetic on that data structure.
Next find out how many days we need to add to `sd` to get to the desired `weekday`. This is just the target weekday minus the current weekday. `weekday` subtraction is unsigned modulo 7. That is, it always returns a value between 0 and 6. `mon - sun` is `days{1}` since `mon` is always 1 day after `sun`. `sun - mon` is `days{6}` since `sun` is always 6 days after `mon`. Next find out how many days we need to add to `sd` to get to the desired `weekday`. This is just the target weekday minus the current weekday. `weekday` subtraction is unsigned modulo 7. That is, it always returns a value between 0 and 6. `Monday - Sunday` is `days{1}` since `Monday` is always 1 day after `Sunday`. `Sunday - Monday` is `days{6}` since `Sunday` is always 6 days after `Monday`.
Above if `target == weekday{sd}`, then we don't add any days at all because `ymd` already has the desired `weekday`. Else we add up to 6 days. Then the return implicitly converts back to a `year_month_day`. Above if `target == weekday{sd}`, then we don't add any days at all because `ymd` already has the desired `weekday`. Else we add up to 6 days. Then the return implicitly converts back to a `year_month_day`.
@@ -927,10 +927,10 @@ to_CCSDS(date::year y, std::chrono::microseconds us)
{ {
using namespace date; using namespace date;
using namespace std::chrono; using namespace std::chrono;
auto utc = to_utc_time(sys_days{y/jan/1}) + us; auto utc = to_utc_time(sys_days{y/January/1}) + us;
auto sys = to_sys_time(utc); auto sys = to_sys_time(utc);
auto dp = floor<days>(sys); auto dp = floor<days>(sys);
auto d = dp - sys_days{1958_y/jan/1}; auto d = dp - sys_days{1958_y/January/1};
us = utc - to_utc_time(dp); us = utc - to_utc_time(dp);
auto ms = duration_cast<milliseconds>(us); auto ms = duration_cast<milliseconds>(us);
us -= ms; us -= ms;
@@ -957,8 +957,8 @@ http://stackoverflow.com/q/19290421/576911
And I decided to see if I could answer it (here) using this library. The question asks: How can I get the number of months between two dates? And it gives two example dates: And I decided to see if I could answer it (here) using this library. The question asks: How can I get the number of months between two dates? And it gives two example dates:
```c++ ```c++
auto d1 = 1_d/oct/2013; auto d1 = 1_d/October/2013;
auto d2 = 30_d/oct/2016; auto d2 = 30_d/October/2016;
``` ```
(I've converted the syntax to that of this library). (I've converted the syntax to that of this library).
@@ -1089,8 +1089,7 @@ main()
using namespace date; using namespace date;
// Dave was born April 24, 1954. 10:03 AM pst // Dave was born April 24, 1954. 10:03 AM pst
// Want to know when he is 2 Gigaseconds old // Want to know when he is 2 Gigaseconds old
auto birthday = make_zoned("America/Los_Angeles", zoned_time birthday{"America/Los_Angeles", local_days{April/24/1954} + 10h + 3min};
local_days{apr/24/1954} + 10h + 3min);
std::cout << "born : " << birthday << '\n'; std::cout << "born : " << birthday << '\n';
birthday = birthday.get_sys_time() + 2'000'000'000s; birthday = birthday.get_sys_time() + 2'000'000'000s;
std::cout << "2Gs birthday: " << birthday << '\n'; std::cout << "2Gs birthday: " << birthday << '\n';
@@ -1117,7 +1116,7 @@ Assuming the birthdate is exactly synchronized with TAI (offset by the timezone)
```c++ ```c++
auto zone = locate_zone("America/Los_Angeles"); auto zone = locate_zone("America/Los_Angeles");
auto birthday = to_tai_time(make_zoned(zone, auto birthday = to_tai_time(make_zoned(zone,
local_days{apr/24/1954} + 10h + 3min - 10s).get_sys_time()); local_days{April/24/1954} + 10h + 3min - 10s).get_sys_time());
``` ```
We have to subtract 10s manually because we want the birthday to be `1954-04-24 18:03:00 TAI` and without that 10s subtraction we have UTC modeled back to 1954 instead of modeling TAI in 1954. Then we add the 2Gs in `tai_time` and convert that result back to `sys_time`, and then to a `zoned_time`: We have to subtract 10s manually because we want the birthday to be `1954-04-24 18:03:00 TAI` and without that 10s subtraction we have UTC modeled back to 1954 instead of modeling TAI in 1954. Then we add the 2Gs in `tai_time` and convert that result back to `sys_time`, and then to a `zoned_time`: