Updated Examples and Recipes (markdown)

Howard Hinnant
2019-03-31 17:15:26 -04:00
parent 102dc3a2b5
commit 5ad7a35077

@@ -1096,7 +1096,7 @@ main()
} }
``` ```
One first creates the local time, and then pairs that to the time zone "America/Los_Angeles" using `make_zoned`. Then add 2Gs to the `sys_time` (not the `local_time`) of `birthday`. This outputs: One first creates the local time, and then pairs that to the time zone "America/Los_Angeles" using `zoned_time`. Then add 2Gs to the `sys_time` (not the `local_time`) of `birthday`. This outputs:
born : 1954-04-24 10:03:00 PST born : 1954-04-24 10:03:00 PST
2Gs birthday: 2017-09-08 14:36:20 PDT 2Gs birthday: 2017-09-08 14:36:20 PDT
@@ -1115,14 +1115,14 @@ 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(zoned_time{zone,
local_days{April/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`:
```c++ ```c++
auto Day2Gs = make_zoned(zone, to_sys_time(birthday + 2'000'000'000s)); zoned_time Day2Gs{zone, to_sys_time(birthday + 2'000'000'000s)};
``` ```
Now the output is: Now the output is:
@@ -1149,12 +1149,12 @@ int main()
// calculating the year and the day of the year // calculating the year and the day of the year
const auto year = ymd.year(); const auto year = ymd.year();
const auto year_day = daypoint - sys_days{year/jan/0}; const auto year_day = daypoint - sys_days{year/January/0};
std::cout << year << '-' << std::setfill('0') << std::setw(3) << year_day.count() << std::endl; std::cout << year << '-' << std::setfill('0') << std::setw(3) << year_day.count() << std::endl;
// inverse calculation and check // inverse calculation and check
assert(ymd == year_month_day{sys_days{year/jan/0} + year_day}); assert(ymd == year_month_day{sys_days{year/January/0} + year_day});
} }
``` ```
@@ -1175,7 +1175,7 @@ main()
{ {
using namespace std::chrono; using namespace std::chrono;
using namespace date; using namespace date;
auto base = make_zoned("America/New_York", local_days{mar/11/2016} + 9h); zoned_time base{"America/New_York", local_days{March/11/2016} + 9h};
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
{ {
std::cout << format("%F %T %z", base) << '\n'; std::cout << format("%F %T %z", base) << '\n';
@@ -1226,7 +1226,7 @@ find_by_abbrev(date::sys_time<Duration> tp, const std::string& abbrev)
for (auto& z : db.zones) for (auto& z : db.zones)
{ {
if (z.get_info(tp).abbrev == abbrev) if (z.get_info(tp).abbrev == abbrev)
results.push_back(make_zoned(&z, tp)); results.emplace_back(&z, tp);
} }
return results; return results;
} }
@@ -1297,13 +1297,13 @@ find_by_abbrev(date::local_time<Duration> tp, const std::string& abbrev)
{ {
case local_info::unique: case local_info::unique:
if (i.first.abbrev == abbrev) if (i.first.abbrev == abbrev)
results.push_back(make_zoned(&z, tp)); results.emplace_back(&z, tp);
break; break;
case local_info::ambiguous: case local_info::ambiguous:
if (i.first.abbrev == abbrev) if (i.first.abbrev == abbrev)
results.push_back(make_zoned(&z, tp, choose::earliest)); results.emplace_back(&z, tp, choose::earliest);
else if (i.second.abbrev == abbrev) else if (i.second.abbrev == abbrev)
results.push_back(make_zoned(&z, tp, choose::latest)); results.emplace_back(&z, tp, choose::latest);
break; break;
default: default:
break; break;
@@ -1313,7 +1313,7 @@ find_by_abbrev(date::local_time<Duration> tp, const std::string& abbrev)
} }
``` ```
A `local_time` may or may not have a unique mapping to UTC. It might be unique, it might be ambiguous, or it might not exist at all. This function discovers if the mapping is unique, ambiguous or non-existent with `i.result`. If it is unique, the logic is exactly as with the `find_by_abbrev` for `sys_time` search. Note that `make_zoned` knows the difference between a `sys_time` and a `local_time`, and always does the right thing. A `local_time` may or may not have a unique mapping to UTC. It might be unique, it might be ambiguous, or it might not exist at all. This function discovers if the mapping is unique, ambiguous or non-existent with `i.result`. If it is unique, the logic is exactly as with the `find_by_abbrev` for `sys_time` search. Note that `zoned_time` knows the difference between a `sys_time` and a `local_time`, and always does the right thing.
If the mapping is ambiguous, then there are two potential mappings from `{local time, time zone abbrev}` to UTC. If the first matches up with the abbreviation then the first is selected, else if the second matches up with the abbreviation then the second is selected. Else neither is selected. If the mapping is ambiguous, then there are two potential mappings from `{local time, time zone abbrev}` to UTC. If the first matches up with the abbreviation then the first is selected, else if the second matches up with the abbreviation then the second is selected. Else neither is selected.
@@ -1355,8 +1355,8 @@ main()
auto& db = get_tzdb(); auto& db = get_tzdb();
for (auto const& z : db.zones) for (auto const& z : db.zones)
{ {
auto begin = sys_days{jan/1/year::min()} + 0s; auto begin = sys_days{January/1/year::min()} + 0s;
auto end = sys_days{jan/1/2035} + 0s; auto end = sys_days{January/1/2035} + 0s;
do do
{ {
auto info = z.get_info(begin); auto info = z.get_info(begin);
@@ -1425,8 +1425,8 @@ main()
for (auto& z : db.zones) for (auto& z : db.zones)
{ {
++total; ++total;
auto info1 = z.get_info(sys_days{y/jan/15}); auto info1 = z.get_info(sys_days{y/January/15});
auto info2 = z.get_info(sys_days{y/jul/15}); auto info2 = z.get_info(sys_days{y/July/15});
if (info1.save != 0min || info2.save != 0min) if (info1.save != 0min || info2.save != 0min)
++use_daylight; ++use_daylight;
} }
@@ -1519,7 +1519,7 @@ to_sys_days(System::TDate td)
{ {
using namespace date; using namespace date;
return sys_days(days{static_cast<int>(td)} - return sys_days(days{static_cast<int>(td)} -
(sys_days{1970_y/jan/1} - sys_days{1899_y/dec/30})); (sys_days{1970_y/January/1} - sys_days{1899_y/December/30}));
} }
``` ```
@@ -1531,7 +1531,7 @@ to_TDate(date::sys_days sd)
{ {
using namespace date; using namespace date;
return System::TDate(static_cast<int>((sd.time_since_epoch() + return System::TDate(static_cast<int>((sd.time_since_epoch() +
(sys_days{1970_y/jan/1} - sys_days{1899_y/dec/30})).count())); (sys_days{1970_y/January/1} - sys_days{1899_y/December/30})).count()));
} }
``` ```
@@ -1548,10 +1548,10 @@ main()
std::cout << to_sys_days(TDate{-1}) << '\n'; std::cout << to_sys_days(TDate{-1}) << '\n';
std::cout << to_sys_days(TDate{35065}) << '\n'; std::cout << to_sys_days(TDate{35065}) << '\n';
std::cout << (int)to_TDate(1899_y/dec/30) << '\n'; std::cout << (int)to_TDate(1899_y/December/30) << '\n';
std::cout << (int)to_TDate(1900_y/jan/1) << '\n'; std::cout << (int)to_TDate(1900_y/January/1) << '\n';
std::cout << (int)to_TDate(1899_y/dec/29) << '\n'; std::cout << (int)to_TDate(1899_y/December/29) << '\n';
std::cout << (int)to_TDate(1996_y/jan/1) << '\n'; std::cout << (int)to_TDate(1996_y/January/1) << '\n';
} }
``` ```
@@ -1598,7 +1598,7 @@ to_sys_time(System::TDateTime dt)
auto t = d - ft; auto t = d - ft;
ft = d + t; ft = d + t;
} }
ft -= sys_days{1970_y/jan/1} - sys_days{1899_y/dec/30}; ft -= sys_days{1970_y/January/1} - sys_days{1899_y/December/30};
return round<D>(ft); return round<D>(ft);
} }
``` ```
@@ -1618,7 +1618,7 @@ to_TDateTime(date::sys_time<D> tp)
using namespace std::chrono; using namespace std::chrono;
using fdays = duration<double, days::period>; using fdays = duration<double, days::period>;
using ftime = time_point<system_clock, fdays>; using ftime = time_point<system_clock, fdays>;
auto ft = ftime{tp} + (sys_days{1970_y/jan/1} - sys_days{1899_y/dec/30}); auto ft = ftime{tp} + (sys_days{1970_y/January/1} - sys_days{1899_y/December/30});
if (ft >= ftime{}) if (ft >= ftime{})
return System::TDateTime(ft.time_since_epoch().count()); return System::TDateTime(ft.time_since_epoch().count());
auto d = floor<days>(ft); auto d = floor<days>(ft);
@@ -1641,10 +1641,10 @@ main()
std::cout << to_sys_time<minutes>(TDateTime{-1.25}) << '\n'; std::cout << to_sys_time<minutes>(TDateTime{-1.25}) << '\n';
std::cout << to_sys_time<minutes>(TDateTime{35065.}) << '\n'; std::cout << to_sys_time<minutes>(TDateTime{35065.}) << '\n';
std::cout << (double)to_TDateTime(sys_days{1899_y/dec/30} + 0min) << '\n'; std::cout << (double)to_TDateTime(sys_days{1899_y/December/30} + 0min) << '\n';
std::cout << (double)to_TDateTime(sys_days{1900_y/jan/1} + 18h + 0min) << '\n'; std::cout << (double)to_TDateTime(sys_days{1900_y/January/1} + 18h + 0min) << '\n';
std::cout << (double)to_TDateTime(sys_days{1899_y/dec/29} + 6h + 0min) << '\n'; std::cout << (double)to_TDateTime(sys_days{1899_y/December/29} + 6h + 0min) << '\n';
std::cout << (double)to_TDateTime(sys_days{1996_y/jan/1} + 0min) << '\n'; std::cout << (double)to_TDateTime(sys_days{1996_y/January/1} + 0min) << '\n';
} }
``` ```
@@ -1671,7 +1671,7 @@ to_sys_days(QDate qd)
{ {
using namespace date; using namespace date;
return sys_days{days{qd.toJulianDay()} - return sys_days{days{qd.toJulianDay()} -
(sys_days{1970_y/jan/1} - sys_days{year{-4713}/nov/24})}; (sys_days{1970_y/January/1} - sys_days{year{-4713}/November/24})};
} }
QDate QDate
@@ -1679,7 +1679,7 @@ to_QDate(date::sys_days sd)
{ {
using namespace date; using namespace date;
return QDate::fromJulianDay((sd.time_since_epoch() + return QDate::fromJulianDay((sd.time_since_epoch() +
(sys_days{1970_y/jan/1} - sys_days{year{-4713}/nov/24})).count()); (sys_days{1970_y/January/1} - sys_days{year{-4713}/November/24})).count());
} }
``` ```
@@ -1830,7 +1830,7 @@ print_line_of_calendar_month(std::ostream& os, date::year_month const ym,
void void
print_calendar_year(std::ostream& os, unsigned const cols = 3, print_calendar_year(std::ostream& os, unsigned const cols = 3,
date::year const y = current_year(), date::year const y = current_year(),
date::weekday const firstdow = date::sun) date::weekday const firstdow = date::Sunday)
{ {
using namespace date; using namespace date;
if (cols == 0 || 12 % cols != 0) if (cols == 0 || 12 % cols != 0)
@@ -1948,7 +1948,7 @@ And that concludes the hardest part of the hardest function for this entire util
void void
print_calendar_year(std::ostream& os, unsigned const cols = 3, print_calendar_year(std::ostream& os, unsigned const cols = 3,
date::year const y = current_year(), date::year const y = current_year(),
date::weekday const firstdow = date::sun); date::weekday const firstdow = date::Sunday);
``` ```
This function prints the yearly calendar to `os` by calling the functions we've already defined. The calendar is in a format of `cols` by `rows` months, where `cols` is input by the client and represents how many months you want to print out horizontally. This argument must be one of `[1, 2, 3, 4, 6, 12]`. The example output above defaulted this to 3 months across by 4 down. The year can be input, or defaults to the current year UTC. And the day of the week which the calendar starts with can be specified and defaults to Sunday. This function prints the yearly calendar to `os` by calling the functions we've already defined. The calendar is in a format of `cols` by `rows` months, where `cols` is input by the client and represents how many months you want to print out horizontally. This argument must be one of `[1, 2, 3, 4, 6, 12]`. The example output above defaulted this to 3 months across by 4 down. The year can be input, or defaults to the current year UTC. And the day of the week which the calendar starts with can be specified and defaults to Sunday.
@@ -1966,7 +1966,7 @@ This program can now be used to localize and output a wide variety of calendars.
```c++ ```c++
using namespace date::literals; using namespace date::literals;
std::cout.imbue(std::locale("de_DE")); std::cout.imbue(std::locale("de_DE"));
print_calendar_year(std::cout, 4, 2016_y, mon); print_calendar_year(std::cout, 4, 2016_y, Monday);
``` ```
which outputs: which outputs: