Rename day_point to sys_days

Howard Hinnant
2016-05-21 11:13:46 -04:00
parent 2df87145c3
commit 813a75305c

@@ -29,7 +29,7 @@ int y=2015, m=7, d=30, h=12, min=34, s=56;
auto ymd = year(y)/m/d; // Yields a year_month_day type auto ymd = year(y)/m/d; // Yields a year_month_day type
if (!ymd.ok()) if (!ymd.ok())
throw std::runtime_error("Invalid date"); throw std::runtime_error("Invalid date");
system_clock::time_point = day_point(ymd) + system_clock::time_point tp = sys_days(ymd) +
hours(h) + minutes(min) + seconds(s); hours(h) + minutes(min) + seconds(s);
``` ```
@@ -47,7 +47,7 @@ void to_time_point(const std::tm& t,
auto ymd = year(y)/(t.tm_mon+1)/t.tm_mday; // Yields a year_month_day type auto ymd = year(y)/(t.tm_mon+1)/t.tm_mday; // Yields a year_month_day type
if (!ymd.ok()) if (!ymd.ok())
throw std::runtime_error("Invalid date"); throw std::runtime_error("Invalid date");
tp = day_point(ymd) + tp = sys_days(ymd) +
hours(t.tm_hour) + minutes(t.tm_min) + seconds(t.tm_sec); hours(t.tm_hour) + minutes(t.tm_min) + seconds(t.tm_sec);
} }
@@ -87,10 +87,9 @@ std::tm to_calendar_time(std::chrono::time_point<Clock, Duration> tp)
auto ymd = year_month_day(date); auto ymd = year_month_day(date);
auto weekday = year_month_weekday(date).weekday_indexed().weekday(); auto weekday = year_month_weekday(date).weekday_indexed().weekday();
auto tod = make_time(tp - date); auto tod = make_time(tp - date);
days daysSinceJan1 = date - day_point(ymd.year()/1/1); days daysSinceJan1 = date - sys_days(ymd.year()/1/1);
std::tm result; std::tm result{};
std::memset(&result, 0, sizeof(result));
result.tm_sec = tod.seconds().count(); result.tm_sec = tod.seconds().count();
result.tm_min = tod.minutes().count(); result.tm_min = tod.minutes().count();
result.tm_hour = tod.hours().count(); result.tm_hour = tod.hours().count();
@@ -119,7 +118,7 @@ The following function will "normalize" a `year_month_day`, much like `mktime` n
{ {
using namespace date; using namespace date;
ymd += months{0}; ymd += months{0};
ymd = day_point(ymd); ymd = sys_days{ymd};
return ymd; return ymd;
} }
@@ -127,11 +126,11 @@ The first line simply adds 0 months to the `ymd`. If `ymd.month()` is 0, this w
The second line will "normalize" the day field. The second line requires that the month field is already normalized. For example `2015_y/dec/32` will become `2016_y/jan/1`. If the day field is already in range, there will be no change. The second line will "normalize" the day field. The second line requires that the month field is already normalized. For example `2015_y/dec/32` will become `2016_y/jan/1`. If the day field is already in range, there will be no change.
The conversion from `year_month_day` to `day_point` calls this algorithm: The conversion from `year_month_day` to `sys_days` calls this algorithm:
http://howardhinnant.github.io/date_algorithms.html#days_from_civil http://howardhinnant.github.io/date_algorithms.html#days_from_civil
And the conversion from `day_point` back to `year_month_day` calls this algorithm: And the conversion from `sys_days` back to `year_month_day` calls this algorithm:
http://howardhinnant.github.io/date_algorithms.html#civil_from_days http://howardhinnant.github.io/date_algorithms.html#civil_from_days
@@ -145,7 +144,7 @@ Example:
std::cout << ymd << (ymd.ok() ? "\n" : " invalid date\n"); std::cout << ymd << (ymd.ok() ? "\n" : " invalid date\n");
ymd += months{0}; ymd += months{0};
std::cout << ymd << (ymd.ok() ? "\n" : " invalid date\n"); std::cout << ymd << (ymd.ok() ? "\n" : " invalid date\n");
ymd = day_point(ymd); ymd = sys_days{ymd};
std::cout << ymd << (ymd.ok() ? "\n" : " invalid date\n"); std::cout << ymd << (ymd.ok() ? "\n" : " invalid date\n");
} }
@@ -181,10 +180,10 @@ Here is a function to perform that conversion:
{ {
using namespace date; using namespace date;
using namespace std::chrono; using namespace std::chrono;
auto utc = utc_clock::sys_to_utc(day_point{y/jan/1}) + us; auto utc = utc_clock::sys_to_utc(sys_days{y/jan/1}) + us;
auto sys = utc_clock::utc_to_sys(utc); auto sys = utc_clock::utc_to_sys(utc);
auto dp = floor<days>(sys); auto dp = floor<days>(sys);
auto d = dp - day_point{1958_y/jan/1}; auto d = dp - sys_days{1958_y/jan/1};
us = utc - utc_clock::sys_to_utc(dp); us = utc - utc_clock::sys_to_utc(dp);
auto ms = duration_cast<milliseconds>(us); auto ms = duration_cast<milliseconds>(us);
us -= ms; us -= ms;
@@ -226,12 +225,12 @@ This creates two `year_month` objects and subtracts them. This gives a `std::ch
36 36
To include the influence of the day-fields, it is best to convert `d1` and `d2` to `day_point`s: To include the influence of the day-fields, it is best to convert `d1` and `d2` to `sys_days `s:
auto dp1 = day_point(d1); auto dp1 = sys_days(d1);
auto dp2 = day_point(d2); auto dp2 = sys_days(d2);
Now we could (for example) subtract the two `day_point`s, and round the result to the nearest integral month: Now we could (for example) subtract the two `sys_days `s, and round the result to the nearest integral month:
std::cout << round<months>(dp2-dp1).count() << '\n'; std::cout << round<months>(dp2-dp1).count() << '\n';
@@ -260,11 +259,11 @@ The [ISO week date](https://en.wikipedia.org/wiki/ISO_week_date) is an internati
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). 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`: Also like `<date.h>`, you can implicitly convert a ISO week date to `sys_days `, and vice-versa. For convenience, an alias of `date:: sys_days ` exists as `iso_week:: sys_days `:
iso_week::day_point dp = iso_date; iso_week:: sys_days 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. And recall that `sys_days ` 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 now = std::chrono::system_clock::now();
auto dp = date::floor<iso_week::days>(now); auto dp = date::floor<iso_week::days>(now);
@@ -276,7 +275,7 @@ Which just output for me:
2016-W11-Sat 03:07:02.460737 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`: And because `iso_week:year_weeknum_weekday` is implicitly convertible to and from `sys_days `, that makes it immediately (and explicitly) convertible to any other calendar system that is implicitly convertible to and from `sys_days `:
auto civil_date = date::year_month_day{iso_date}; auto civil_date = date::year_month_day{iso_date};
std::cout << civil_date << ' ' << time << '\n'; std::cout << civil_date << ' ' << time << '\n';
@@ -285,7 +284,7 @@ which outputs:
2016-03-19 03:07:02.460737 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. And there you have it: `sys_days ` is a _Rosetta Stone_ for translating _any_ calendar to any other calendar. Just make your calendar convert to and from `sys_days `, and you have interoperability with _every_ other calendar which does so.
using namespace date::literals; using namespace date::literals;
auto today = 2016_y/mar/19; auto today = 2016_y/mar/19;
@@ -301,7 +300,7 @@ Output:
Coptic : 1732-07-10 Coptic : 1732-07-10
iso_week: 2016-W11-Sat 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! 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 `sys_days`), and your calendar is now part of the club! Contribute your calendar so we can all use it!
<a name="birthday2gs"></a> <a name="birthday2gs"></a>
### 2Gs Birthday ### 2Gs Birthday
@@ -321,7 +320,7 @@ This example demonstrates both some simple date arithmetic, and how to handle di
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 birth = day_point{apr/24/1954} + 10h + 3min; auto birth = sys_days{apr/24/1954} + 10h + 3min;
auto z = locate_zone("America/Los_Angeles"); auto z = locate_zone("America/Los_Angeles");
auto t = z->to_sys(birth); auto t = z->to_sys(birth);
t += 2'000'000'000s; t += 2'000'000'000s;
@@ -353,12 +352,12 @@ An [ordinal date](https://en.wikipedia.org/wiki/Ordinal_date) consists of a year
// 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 - day_point{year/jan/0}; const auto year_day = daypoint - sys_days{year/jan/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{day_point{year/jan/0} + year_day}); assert(ymd == year_month_day{sys_days{year/jan/0} + year_day});
} }
<a name="tz_search"></a> <a name="tz_search"></a>
@@ -378,8 +377,8 @@ Let's say you want to search the globe, and all time, for time zones when the da
auto& db = get_tzdb(); auto& db = get_tzdb();
for (auto const& z : db.zones) for (auto const& z : db.zones)
{ {
auto begin = day_point{jan/1/year::min()} + 0s; auto begin = sys_days{jan/1/year::min()} + 0s;
auto end = day_point{jan/1/2035} + 0s; auto end = sys_days{jan/1/2035} + 0s;
do do
{ {
auto info = z.get_info(begin, tz::utc); auto info = z.get_info(begin, tz::utc);
@@ -444,8 +443,8 @@ Ever wonder how the global use of daylight saving time is trending with time? H
for (auto& z : db.zones) for (auto& z : db.zones)
{ {
++total; ++total;
auto info1 = z.get_info(day_point{y/jan/15}, tz::utc); auto info1 = z.get_info(sys_days{y/jan/15}, tz::utc);
auto info2 = z.get_info(day_point{y/jul/15}, tz::utc); auto info2 = z.get_info(sys_days{y/jul/15}, tz::utc);
if (info1.save != 0min || info2.save != 0min) if (info1.save != 0min || info2.save != 0min)
++use_daylight; ++use_daylight;
} }