From 2f020e2654c41630f0b7d14c85bd4d0894405527 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Sat, 7 May 2016 16:05:21 -0400 Subject: [PATCH] Added local_time, and renamed day_point to sys_days --- date.html | 406 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 318 insertions(+), 88 deletions(-) diff --git a/date.html b/date.html index d01eefe..4611d76 100644 --- a/date.html +++ b/date.html @@ -26,7 +26,7 @@

Howard E. Hinnant
-2015-09-19
+2016-05-07
Creative
 Commons License
This work is licensed @@ -118,7 +118,7 @@ This library is composed of many types. But here are the most important ones:

    -
  1. day_point: A count of days since system_clock's epoch. This +
  2. sys_days: A count of days since system_clock's epoch. This is a serial-based time point with a resolution of one day.
  3. year_month_day: A type that holds a year (e.g. 2015), a month (encoded as 1 thru 12), and a day (encoded as 1 thru 31). This is a field-based time @@ -252,9 +252,9 @@ constexpr auto x3 = sun[4]/mar/2015;

    The type constructed is year_month_weekday which will implicitly convert to -and from a day_point. If you want to convert to a +and from a sys_days. If you want to convert to a year_month_day you can do so explicitly, which will implicitly convert to -day_point and back: +sys_days and back:

    @@ -310,9 +310,9 @@ cout << x2 << '\n';
     

    Example: Today

    -To get today as a day_point, use system_clock::now() and +To get today as a sys_days, use system_clock::now() and floor to convert the time_point to a -day_point: +sys_days:

    @@ -329,7 +329,7 @@ Currently this outputs for me:
     

    -To get today as a year_month_day, get a day_point as above and +To get today as a year_month_day, get a sys_days as above and convert it to a year_month_day:

    @@ -347,7 +347,7 @@ Which again currently outputs for me:

    -To get today as a year_month_weekday, get a day_point as above and +To get today as a year_month_weekday, get a sys_days as above and convert it to a year_month_weekday:

    @@ -522,7 +522,7 @@ with noexcept.

    A few of the operations have a precondition that ok() == true. These are -generally conversions to day_point, and month-oriented and weekday-oriented +generally conversions to sys_days, and month-oriented and weekday-oriented arithmetic. Anywhere there is a precondition, and those places are few, the precondition is checkable with ok().

    @@ -543,7 +543,7 @@ In N Pacifico, Meredith and Lakos present a thorough survey of date types and their performance. This library has been strongly influenced by this excellent paper. year_month_day is equivalent to what N3344 terms YMD_4. And -day_point is equivalent to what N3344 terms HH_SERIAL_RAW_4. +sys_days is equivalent to what N3344 terms HH_SERIAL_RAW_4.

    @@ -561,22 +561,22 @@ And additionally, just provide the API for each data structure that it can do ef

  4. Field types are good at returning the values of the fields. Serial types aren't (except for weekdays). So year_month_day has accessors for year, -month and day. And day_point does not. +month and day. And sys_days does not.

  5. Field types are good at month and year-oriented arithmetic. Serial types aren't. So year_month_day has month and year-oriented arithmetic. And -day_point does not. +sys_days does not.

  6. Serial types are good at day-oriented arithmetic. Field types aren't. -So day_point has day-oriented arithmetic. And year_month_day +So sys_days has day-oriented arithmetic. And year_month_day does not. Though one can perform day-oriented arithmetic on the day field of a year_month_day, with no impact on the other fields.

  7. To efficiently compute a day of the week, one first needs to compute a serial date. So -weekday is constructible from day_point. +weekday is constructible from sys_days.

  8. @@ -692,24 +692,24 @@ a year_month_day is zero, at least in optimized builds.

    -A similar experiment is made for constructing a day_point from a count of +A similar experiment is made for constructing a sys_days from a count of days held in an int. To do this one must first create a days -duration, and then construct the day_point from the days +duration, and then construct the sys_days from the days duration. This is contrasted with the very simplistic struct SERIAL_4.

    - + @@ -784,13 +784,13 @@ Ltmp4:

    It is easy to see that the generated code is identical, and thus there is no overhead -associated with the day_point type. It is also noteworthy that the code for +associated with the sys_days type. It is also noteworthy that the code for this construction does not actually come from this date library, but instead comes from your std::lib header <chrono>. days is nothing but a type-alias for a std::chrono::duration, and -day_point is nothing but a type-alias for a +sys_days is nothing but a type-alias for a std::chrono::time_point (thus the inspiration for the name -day_point). So this is also evidence that there is zero overhead for the +sys_days). So this is also evidence that there is zero overhead for the type-safe system of the <chrono> library.

    @@ -817,7 +817,7 @@ time_point shift_epoch(time_point t) { using namespace date; - return t + (day_point(jan/1/2000) - day_point(jan/1/1970)); + return t + (sys_days(jan/1/2000) - sys_days(jan/1/1970)); } @@ -895,7 +895,7 @@ seconds between these two epochs ... who knew?

    clang generates identical assembly for these two functions at -O2 and higher. That -is, the sub-expression (day_point(jan/1/2000) - day_point(jan/1/1970)) is +is, the sub-expression (sys_days(jan/1/2000) - sys_days(jan/1/1970)) is reduced down to a number of days (10,957) at compile time, and then this sub-expression, which has type days is added to a time_point with a resolution of seconds, which causes the compiler to convert @@ -954,7 +954,7 @@ This currently outputs for me:

    One can turn that into a time_point with the precision of a day (which -has a type alias called day_point) with: +has a type alias called sys_days) with:

    @@ -1039,8 +1039,8 @@ utc_offset_Eastern_US(std::chrono::system_clock::time_point tp)
         constexpr auto EST = -5h;
         constexpr auto EDT = -4h;
         const auto y = year_month_day(floor<days>(tp)).year();
    -    const auto begin = day_point(sun[2]/mar/y) + 2h - EST; // EDT begins at this UTC time
    -    const auto end   = day_point(sun[1]/nov/y) + 2h - EDT; // EST begins at this UTC time
    +    const auto begin = sys_days(sun[2]/mar/y) + 2h - EST; // EDT begins at this UTC time
    +    const auto end   = sys_days(sun[1]/nov/y) + 2h - EDT; // EST begins at this UTC time
         if (tp < begin || end <= tp)
             return EST;
         return EDT;
    @@ -1074,27 +1074,27 @@ std::cout << ymd << ' ' << time << '\n';
     

    Extensibility

    -The hub of this library is day_point. This is a serial-based time +The hub of this library is sys_days. This is a serial-based time point which simply counts the days since (or before) jan/1/1970. And ironically this all important hub is nothing but a type alias to a std-defined type. That is, the central theme this library is built around is nothing more than this:

    -using day_point = std::chrono::time_point<std::chrono::system_clock, days>;
    +using sys_days = std::chrono::time_point<std::chrono::system_clock, days>;
     

    Types such as year_month_day and year_month_weekday provide -implicit conversions to and from day_point, and because of this, the C++ +implicit conversions to and from sys_days, and because of this, the C++ language provides explicit conversions between year_month_day and year_month_weekday.

    You can easily build your own types that implicitly convert to and from -day_point, and when you do, you automatically gain explicit convertibility to -and from every other type which ties into day_point. For example, here is +sys_days, and when you do, you automatically gain explicit convertibility to +and from every other type which ties into sys_days. For example, here is how you could create a custom type that models the ISO week-based calendar:

    @@ -1106,7 +1106,7 @@ class iso_week date::weekday wd_; public: - constexpr iso_week(date::day_point dp) noexcept + constexpr iso_week(date::sys_days dp) noexcept : iso_week(iso_week_from_day_point(dp)) {} @@ -1116,7 +1116,7 @@ public: , wd_(wd) {} - constexpr operator date::day_point() const noexcept + constexpr operator date::sys_days() const noexcept { using namespace date; return iso_week_start(y_) + w_ - weeks{1} + (wd_ - mon); @@ -1130,17 +1130,17 @@ public: private: static constexpr - date::day_point + date::sys_days iso_week_start(date::year y) noexcept { using namespace date; - return day_point(thu[1]/jan/y) - (thu-mon); + return sys_days(thu[1]/jan/y) - (thu-mon); } static constexpr iso_week - iso_week_from_day_point(date::day_point dp) noexcept + iso_week_from_day_point(date::sys_days dp) noexcept { using namespace date; using namespace std::chrono; @@ -1181,22 +1181,22 @@ start of the week-based year.

    With that in mind, one can easily create a field-based data structure that holds a year, a week number, and a day of the week, and then provides conversions -to and from day_point. +to and from sys_days.

    The key points of this class (for interoperability) are the constructor -iso_week(date::day_point dp) and the operator date::day_point(). +iso_week(date::sys_days dp) and the operator date::sys_days().

    To aid in these computations a private helper function is created to compute the -day_point corresponding to the first day of the week-based year. And according +sys_days corresponding to the first day of the week-based year. And according to rule 2, this can be elegantly coded as:

    -return day_point(thu[1]/jan/y) - (thu-mon);
    +return sys_days(thu[1]/jan/y) - (thu-mon);
     

    @@ -1210,8 +1210,8 @@ days Thursday is past Monday.

    -The constructor iso_week(date::day_point dp) has to first discover which -ISO week-based year the day_point dp falls into. Most often this is the +The constructor iso_week(date::sys_days dp) has to first discover which +ISO week-based year the sys_days dp falls into. Most often this is the same as the civil (year_month_day) year number associated dp. But because the week-based year may start a few days earlier or later than jan/1, the week-based year number may be one less or one greater than the @@ -1225,7 +1225,7 @@ return {y, duration_cast<weeks>(dp - start) + weeks{1}, weekday{dp}};

    -The conversion from iso_week to day_point is even easier: +The conversion from iso_week to sys_days is even easier:

    @@ -1311,8 +1311,13 @@ and predictable.
     
    - - + + + + + + + @@ -1341,7 +1346,7 @@ and predictable. - + @@ -1392,7 +1397,7 @@ and predictable. - + + + + + +
    day_point constructor assemblysys_days constructor assembly
    -date::day_point
    +date::sys_days
     make_day_point(int z)
     {
         using namespace date;
    -    return day_point{days{z}};
    +    return sys_days{days{z}};
     }
     
     years
      
    time_point 
     day_point
    time_points 
     sys_time
     sys_days
     sys_seconds
     local_time
     local_days
     local_seconds
      
    types 
     time_of_day
      
    date composition operators 
    conventional syntax
    operators
     
     constexpr year_month operator/(const year& y, const month& m) noexcept;
     constexpr year_month operator/(const year& y, int m) noexcept;
      
     constexpr year_month_weekday_last operator/(const month_weekday_last& mwdl, int y) noexcept;
      
    time_of_day factory functions 
    time_of_day
    factory functions
     
     
     template <class Rep, class Period>
    @@ -1433,13 +1438,21 @@ make_time(std::chrono::hours h, std::chrono::minutes m, std::chrono::seconds s,
               std::chrono::duration<Rep, Period> sub_s, unsigned md) noexcept
     
      
    convenience
    streaming operators
     
     
     template <class Duration>
    -inline
     std::ostream&
    -operator<<(std::ostream& os,
    -           const std::chrono::time_point<std::chrono::system_clock, Duration>& tp);
    +operator<<(std::ostream& os, const sys_time<Duration>& tp);
    +
      +
    +template <class Duration>
    +std::ostream&
    +operator<<(std::ostream& os, const local_time<Duration>& tp);
     
    @@ -1458,7 +1471,7 @@ in namespace date_literals and imported into namespace dateis accepted for use with SI. days is the resultant type when subtracting two -day_points. +sys_dayss.

     using days = std::chrono::duration
    @@ -1511,20 +1524,109 @@ using months = std::chrono::duration
         <int, std::ratio_divide<years::period, std::ratio<12>>>;
     
    -

    day_point

    +

    sys_time

    -day_point is a std::chrono::time_point using +sys_time is a convenience template alias for creating a +system_clock::time_point but of arbitrary precision. This family of types +represents "system time", which closely models UTC. See utc_time in +tz.h for a variation of sys_time that accurately takes +leap seconds into account when subtracting time_points. +

    +
    +template <class Duration>
    +    using sys_time = std::chrono::time_point<std::chrono::system_clock, Duration>;
    +
    +
    + +

    sys_days

    + +
    +

    +sys_days is a std::chrono::time_point using std::chrono::system_clock and days. This makes -day_point interoperable with +sys_days interoperable with std::chrono::system_clock::time_point. It is simply a count of days since the epoch of std::chrono::system_clock which in every implementation is -Jan. 1, 1970. day_point is a serial-based time point with a resolution of +Jan. 1, 1970. sys_days is a serial-based time point with a resolution of days.

    -using day_point = std::chrono::time_point<std::chrono::system_clock, days>;
    +using sys_days = sys_time<days>;
    +
    +
    + +

    sys_seconds

    + +
    +

    +sys_seconds is a std::chrono::time_point using +std::chrono::system_clock and std::chrono::seconds. +This makes sys_seconds interoperable with +std::chrono::system_clock::time_point. It is simply a count of +non-leap seconds since the epoch of +std::chrono::system_clock which in every implementation is Jan. 1, +1970 00:00:00 UTC. sys_seconds is a serial-based time point with a +resolution of seconds. sys_seconds is also widely known +as Unix Time. +

    +
    +using sys_days = sys_time<std::chrono::seconds>;
    +
    +
    + +

    local_time

    + +
    +

    +local_time is a convenience template alias for creating a +time_point of arbitrary precision which is not based on any clock at all. +This family of types represents a time not associated with any time zone. It is handy +in disambiguating calendar timestamps referring to an unspecified timezone, and those +referring to UTC. +

    +

    +For example, we can say that the upcoming 2017 New Years will be commonly +celebrated at local_time<days>{2017_y/jan/1} + 0s. For those +in a time zone with a zero offset from UTC, it will be celebrated at the +concrete time of sys_days{2017_y/jan/1} + 0s. These two timestamps +have different types, though both have the exact same representation (a count of +seconds), because they mean two subtly different things, and are both +quite useful. +

    + +
    +struct local_t {};
    +
    +template <class Duration>
    +    using sys_time = std::chrono::time_point<local_t, Duration>;
    +
    +
    + +

    local_days

    + +
    +

    +local_days is a convient way to write local_time<days>. +The upcoming 2017 New Years will be commonly celebrated at +local_days{2017_y/jan/1} + 0s. +

    + +
    +using local_days = local_time<days>;
    +
    +
    + +

    local_seconds

    + +
    +

    +local_seconds is a convient way to write local_time<seconds>. +

    + +
    +using local_seconds = local_time<std::chrono::seconds>;
     
    @@ -2363,7 +2465,7 @@ static constexpr year year::min() noexcept;

    Returns: A year constructed with the minimum representable year number. This year shall be a value such that -day_point(min()/jan/1) + Unit{0}, where Unit is one of +sys_days(min()/jan/1) + Unit{0}, where Unit is one of microseconds, milliseconds, seconds, minutes, or hours, there shall be no overflow. [Note: nanoseconds is intentionally omitted from this list. — end note] @@ -2378,7 +2480,7 @@ static constexpr year year::max() noexcept;

    Returns: A year constructed with the maximum representable year number. This year shall be a value such that -day_point(max()/dec/31) + Unit{0}, where Unit is one of +sys_days(max()/dec/31) + Unit{0}, where Unit is one of microseconds, milliseconds, seconds, minutes, or hours, there shall be no overflow. [Note: nanoseconds is intentionally omitted from this list. — end note] @@ -2523,7 +2625,8 @@ class weekday unsigned char wd_; // exposition only public: explicit constexpr weekday(unsigned wd) noexcept; - constexpr weekday(const day_point& dp) noexcept; + constexpr weekday(const sys_days& dp) noexcept; + constexpr weekday(const local_days& dp) noexcept; weekday& operator++() noexcept; weekday operator++(int) noexcept; @@ -2577,7 +2680,7 @@ day of the week.

    -A weekday can be implicitly constructed from a day_point. This +A weekday can be implicitly constructed from a sys_days. This is the computation that discovers the day of the week of an arbitrary date.

    @@ -2607,13 +2710,13 @@ explicit constexpr weekday::weekday(unsigned wd) noexcept;
    -constexpr weekday(const day_point& dp) noexcept;
    +constexpr weekday(const sys_days& dp) noexcept;
     

    Effects: Constructs an object of type weekday by computing what day -of the week corresponds to the day_point dp, and representing that day of +of the week corresponds to the sys_days dp, and representing that day of the week in wd_.

    @@ -2622,6 +2725,22 @@ the week in wd_.

    +
    +constexpr weekday(const local_days& dp) noexcept;
    +
    + +
    +

    +Effects: Constructs an object of type weekday by computing what day +of the week corresponds to the local_days dp, and representing that day of +the week in wd_. +

    +

    +The value after construction shall be identical to that constructed from +sys_days{dp.time_since_epoch()}. +

    +
    +
     weekday& weekday::operator++() noexcept;
     
    @@ -3986,7 +4105,8 @@ class year_month_day public: constexpr year_month_day(const date::year& y, const date::month& m, const date::day& d) noexcept; constexpr year_month_day(const year_month_day_last& ymdl) noexcept; - constexpr year_month_day(const day_point& dp) noexcept; + constexpr year_month_day(const sys_days& dp) noexcept; + constexpr year_month_day(const local_days& dp) noexcept; year_month_day& operator+=(const months& m) noexcept; year_month_day& operator-=(const months& m) noexcept; @@ -3997,7 +4117,8 @@ public: constexpr date::month month() const noexcept; constexpr date::day day() const noexcept; - constexpr operator day_point() const noexcept; + constexpr operator sys_days() const noexcept; + constexpr explicit operator local_days() const noexcept; constexpr bool ok() const noexcept; }; @@ -4026,8 +4147,8 @@ and day. year_month_day is a field-based time point w resolution of days. One can observe each field. year_month_day supports years and months oriented arithmetic, but not days oriented arithmetic. For the latter, there is a conversion to -day_point which efficiently supports days oriented arithmetic. -There is also a conversion from day_point. +sys_days which efficiently supports days oriented arithmetic. +There is also a conversion from sys_days. year_month_day is equality and less-than comparable.

    @@ -4064,13 +4185,13 @@ constexpr year_month_day::year_month_day(const year_month_day_last& ymdl) no

    Note: This conversion from year_month_day_last to year_month_day is more efficient than converting a -year_month_day_last to a day_point, and then converting that -day_point to a year_month_day. +year_month_day_last to a sys_days, and then converting that +sys_days to a year_month_day.

    -constexpr year_month_day::year_month_day(const day_point& dp) noexcept;
    +constexpr year_month_day::year_month_day(const sys_days& dp) noexcept;
     
    @@ -4081,7 +4202,21 @@ to the date represented by dp.

    Remarks: For any value of year_month_day, ymd, for which ymd.ok() is true, this equality will also be true: -ymd == year_month_day{day_point{ymd}}. +ymd == year_month_day{sys_days{ymd}}. +

    +
    + +
    +constexpr year_month_day::year_month_day(const local_days& dp) noexcept;
    +
    + +
    +

    +Effects: Constructs an object of type year_month_day which corresponds +to the date represented by dp. +

    +

    +Remarks: Equivalent to constructing with sys_days{dp.time_since_epoch()}.

    @@ -4168,7 +4303,7 @@ constexpr day year_month_day::day() const noexcept;
    -constexpr year_month_day::operator day_point() const noexcept;
    +constexpr year_month_day::operator sys_days() const noexcept;
     
    @@ -4176,9 +4311,32 @@ constexpr year_month_day::operator day_point() const noexcept; Requires: ok() == true.

    -Returns: A day_point which represents the date represented by +Returns: A sys_days which represents the date represented by *this.

    +

    +Remarks: A sys_days which is converted to a year_month_day, +shall have the same value when converted back to a sys_days. The round +trip conversion sequence shall be loss-less. +

    +
    + +
    +constexpr explicit year_month_day::operator local_days() const noexcept;
    +
    + +
    +

    +Requires: ok() == true. +

    +

    +Returns: A local_days which represents the date represented by +*this. +

    +

    +Remarks: Shall return a value equivalent to +local_days{static_cast<sys_days>(*this).time_since_epoch()}. +

    @@ -4372,7 +4530,8 @@ public:
         constexpr date::month_day_last month_day_last() const noexcept;
         constexpr date::day            day()            const noexcept;
     
    -    constexpr operator day_point() const noexcept;
    +    constexpr          operator sys_days() const noexcept;
    +    constexpr explicit operator local_days() const noexcept;
         constexpr bool ok() const noexcept;
     };
     
    @@ -4403,7 +4562,7 @@ std::ostream& operator<<(std::ostream& os, const year_month_day_la
     month.  One can observe each field.  The day field is computed on demand.
     year_month_day_last supports years and months
     oriented arithmetic, but not days oriented arithmetic. For the latter, there
    -is a conversion to day_point which efficiently supports days
    +is a conversion to sys_days which efficiently supports days
     oriented arithmetic.  year_month_day_last is equality and less-than
     comparable.
     

    @@ -4522,7 +4681,7 @@ constexpr day year_month_day_last::day() const noexcept;
    -constexpr year_month_day_last::operator day_point() const noexcept;
    +constexpr year_month_day_last::operator sys_days() const noexcept;
     
    @@ -4530,11 +4689,29 @@ constexpr year_month_day_last::operator day_point() const noexcept; Requires: ok() == true.

    -Returns: A day_point which represents the date represented by +Returns: A sys_days which represents the date represented by *this.

    +
    +constexpr explicit year_month_day_last::operator local_days() const noexcept;
    +
    + +
    +

    +Requires: ok() == true. +

    +

    +Returns: A local_days which represents the date represented by +*this. +

    +

    +Remarks: Shall return a value equivalent to +local_days{static_cast<sys_days>(*this).time_since_epoch()}. +

    +
    +
     constexpr bool year_month_day_last::ok() const noexcept;
     
    @@ -4708,7 +4885,8 @@ class year_month_weekday public: constexpr year_month_weekday(const date::year& y, const date::month& m, const date::weekday_indexed& wdi) noexcept; - constexpr year_month_weekday(const day_point& dp) noexcept; + constexpr year_month_weekday(const sys_days& dp) noexcept; + constexpr year_month_weekday(const local_days& dp) noexcept; year_month_weekday& operator+=(const months& m) noexcept; year_month_weekday& operator-=(const months& m) noexcept; @@ -4721,7 +4899,8 @@ public: constexpr unsigned index() const noexcept; constexpr date::weekday_indexed weekday_indexed() const noexcept; - constexpr operator day_point() const noexcept; + constexpr operator sys_days() const noexcept; + constexpr explicit operator local_days() const noexcept; constexpr bool ok() const noexcept; }; @@ -4746,7 +4925,7 @@ std::ostream& operator<<(std::ostream& os, const year_month_weekda year_month_weekday is a field-based time point with a resolution of days. One can observe each field. year_month_weekday supports years and months oriented arithmetic, but not days -oriented arithmetic. For the latter, there is a conversion to day_point which +oriented arithmetic. For the latter, there is a conversion to sys_days which efficiently supports days oriented arithmetic. year_month_weekday is equality comparable.

    @@ -4773,7 +4952,7 @@ and wdi_ with wdi.
    -constexpr year_month_weekday(const day_point& dp) noexcept;
    +constexpr year_month_weekday(const sys_days& dp) noexcept;
     
    @@ -4784,7 +4963,21 @@ corresponds to the date represented by dp.

    Remarks: For any value of year_month_weekday, ymdl, for which ymdl.ok() is true, this equality will also be -true: ymdl == year_month_weekday{day_point{ymdl}}. +true: ymdl == year_month_weekday{sys_days{ymdl}}. +

    +
    + +
    +constexpr year_month_weekday(const local_days& dp) noexcept;
    +
    + +
    +

    +Effects: Constructs an object of type year_month_weekday which +corresponds to the date represented by dp. +

    +

    +Remarks: Equivalent to constructing with sys_days{dp.time_since_epoch()}.

    @@ -4891,7 +5084,7 @@ constexpr weekday_indexed year_month_weekday::weekday_indexed() const noexcept;
    -constexpr year_month_weekday::operator day_point() const noexcept;
    +constexpr year_month_weekday::operator sys_days() const noexcept;
     
    @@ -4899,11 +5092,29 @@ constexpr year_month_weekday::operator day_point() const noexcept; Requires: ok() == true.

    -Returns: A day_point which represents the date represented by +Returns: A sys_days which represents the date represented by *this.

    +
    +constexpr explicit year_month_weekday::operator local_days() const noexcept;
    +
    + +
    +

    +Requires: ok() == true. +

    +

    +Returns: A local_days which represents the date represented by +*this. +

    +

    +Remarks: Shall return a value equivalent to +local_days{static_cast<sys_days>(*this).time_since_epoch()}. +

    +
    +
     constexpr bool year_month_weekday::ok() const noexcept;
     
    @@ -5048,7 +5259,8 @@ public: constexpr date::weekday weekday() const noexcept; constexpr date::weekday_last weekday_last() const noexcept; - constexpr operator day_point() const noexcept; + constexpr operator sys_days() const noexcept; + constexpr explicit operator local_days() const noexcept; constexpr bool ok() const noexcept; }; @@ -5096,7 +5308,7 @@ std::ostream& operator<<(std::ostream& os, const year_month_weekda days, except that it is restricted to pointing to the last weekday of a year and month. One can observe each field. year_month_weekday_last supports years and months oriented arithmetic, but not days -oriented arithmetic. For the latter, there is a conversion to day_point which +oriented arithmetic. For the latter, there is a conversion to sys_days which efficiently supports days oriented arithmetic. year_month_weekday_last is equality comparable.

    @@ -5215,7 +5427,7 @@ constexpr weekday_last year_month_weekday_last::weekday_last() const noexcept;
    -constexpr year_month_weekday_last::operator day_point() const noexcept;
    +constexpr year_month_weekday_last::operator sys_days() const noexcept;
     
    @@ -5223,11 +5435,29 @@ constexpr year_month_weekday_last::operator day_point() const noexcept; Requires: ok() == true.

    -Returns: A day_point which represents the date represented by +Returns: A sys_days which represents the date represented by *this.

    +
    +constexpr explicit year_month_weekday_last::operator local_days() const noexcept;
    +
    + +
    +

    +Requires: ok() == true. +

    +

    +Returns: A local_days which represents the date represented by +*this. +

    +

    +Remarks: Shall return a value equivalent to +local_days{static_cast<sys_days>(*this).time_since_epoch()}. +

    +
    +
     constexpr bool year_month_weekday_last::ok() const noexcept;