Updated Examples and Recipes (markdown)

HowardHinnant
2016-03-18 23:23:28 -04:00
parent 4defddbb58
commit e40b6110c0

@@ -7,6 +7,7 @@ This page contains examples and recipes contributed by community members. Feel f
- [Converting from {year, microseconds} to CCSDS](#ccsds)
- [Difference in months between two dates](#deltamonths)
- [Parsing ISO strings](http://stackoverflow.com/a/33438989/576911)
- [Working with the ISO week-based year](#iso_week)
- [2Gs Birthday](#birthday2gs)
- [Calculating Ordinal Dates](#year_day)
@@ -246,6 +247,60 @@ This outputs:
These are all reasonable answers to the question, and all easily computable with this library.
<a name="iso_week"></a>
### Working with the ISO week-based year
(by [Howard Hinnant](https://github.com/HowardHinnant))
The [ISO week date](https://en.wikipedia.org/wiki/ISO_week_date) is an internationally recognized system of counting weeks of the year. This is in effect a separate calendar system, though it is closely related to the Gregorian calendar. Instead of specifying a year, month and day, each day is specified by year, week number, and day of the week. For example 2015-W51-Sat is a fully specified date. One can form such a date using the `<iso_week.h>` header like so:
using namespace iso_week::literals;
auto iso_date = 2015_y/51/sat;
Like `<date.h>`, you can specify an ISO week date in any of the three orders: y/wn/wd, wd/wn/y, wn/wd/y (big endian, little endian, mixed (american) endian).
Also like `<date.h>`, you can implicitly convert a ISO week date to `day_point`, and vice-versa. For convenience, an alias of `date::day_point` exists as `iso_week::day_point`:
iso_week::day_point dp = iso_date;
And recall that `day_point` is just a type alias for a `std::chrono::time_point<std::chrono::system_clock, days>`. So the ISO week date (`iso_week:year_weeknum_weekday`) is immediately interoperable with the entire `<chrono>` library, just like `date::year_month_day` is.
auto now = std::chrono::system_clock::now();
auto dp = date::floor<iso_week::days>(now);
iso_week::year_weeknum_weekday iso_date = dp;
auto time = date::make_time(now-dp);
std::cout << iso_date << ' ' << time << '\n';
Which just output for me:
2016-W11-Sat 03:07:02.460737
And because `iso_week:year_weeknum_weekday` is implicitly convertible to and from `day_point`, that makes it immediately (and explicitly) convertible to any other calendar system that is implicitly convertible to and from `day_point`:
auto civil_date = date::year_month_day{iso_date};
std::cout << civil_date << ' ' << time << '\n';
which outputs:
2016-03-19 03:07:02.460737
And there you have it: `day_point` is a _Rosetta Stone_ for translating _any_ calendar to any other calendar. Just make your calendar convert to and from `day_point`, and you have interoperability with _every_ other calendar which does so.
using namespace date::literals;
auto today = 2016_y/mar/19;
std::cout << "civil : " << today << '\n';
std::cout << "Julian : " << julian::year_month_day{today} << '\n';
std::cout << "Coptic : " << coptic::year_month_day{today} << '\n';
std::cout << "iso_week: " << iso_week::year_weeknum_weekday{today} << '\n';
Output:
civil : 2016-03-19
Julian : 2016-03-06
Coptic : 1732-07-10
iso_week: 2016-W11-Sat
This is somewhat of a teaser because as I write this the Julian and Coptic calendars aren't publicly available yet. The software exists, but is not fully tested yet. But more importantly, just follow the recipe in `<iso_week.h>` for your favorite calendar (convert to and from `day_point`), and your calendar is now part of the club! Contribute your calendar so we can all use it!
<a name="birthday2gs"></a>
### 2Gs Birthday
(by [Howard Hinnant](https://github.com/HowardHinnant))