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;
std::array<year_month_day, 5> dates{nan, nan, nan, nan, nan};
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())
{
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:
```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.
@@ -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.
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`.
@@ -927,10 +927,10 @@ to_CCSDS(date::year y, std::chrono::microseconds us)
{
using namespace date;
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 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);
auto ms = duration_cast<milliseconds>(us);
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:
```c++
auto d1 = 1_d/oct/2013;
auto d2 = 30_d/oct/2016;
auto d1 = 1_d/October/2013;
auto d2 = 30_d/October/2016;
```
(I've converted the syntax to that of this library).
@@ -1089,8 +1089,7 @@ main()
using namespace date;
// Dave was born April 24, 1954. 10:03 AM pst
// Want to know when he is 2 Gigaseconds old
auto birthday = make_zoned("America/Los_Angeles",
local_days{apr/24/1954} + 10h + 3min);
zoned_time birthday{"America/Los_Angeles", local_days{April/24/1954} + 10h + 3min};
std::cout << "born : " << birthday << '\n';
birthday = birthday.get_sys_time() + 2'000'000'000s;
std::cout << "2Gs birthday: " << birthday << '\n';
@@ -1117,7 +1116,7 @@ Assuming the birthdate is exactly synchronized with TAI (offset by the timezone)
```c++
auto zone = locate_zone("America/Los_Angeles");
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`: