Search code examples
c++datetimeepochc++-chrono

How is a chrono::year Object Constructed?


I just noticed that is going to have chrono::year. It's constructor takes in an int in the range: [-32767, 32767], however I am unclear what this argument represents.

  • Would this be consistent with tm_year's 1900 origin?
  • Or perhaps time_t's 1970 origin?
  • Or perhaps it's in Anno Domini with a 0 origin?

EDIT:
This is key to the understanding of what is meant by the is_leap function chrono::year offers. Without an origin it's unclear what year is represented here.


Solution

  • In 25.8.1 [time.cal.general]:

    The types in 25.8 describe the civil (Gregorian) calendar and its relationship to sys_days and local_days.

    The wording on this was (is) challenging as the intent is to model the Gregorian calendar (as does C++ currently via the C API) without offending those who follow other calendars.

    I also am just now noting that the word "proleptic" is missing from the spec, and should probably be added in a strategic spot.

    To directly answer the question, the integral associated with std::chrono::year is the Anno Domini reference, as defined by Pope Gregory in 1582, but running both backwards and forwards in time. As I write this, the year is 2018y.

    And (answering Jonathan Mee's comment below), this program:

    #include <chrono>
    #include <iostream>
    
    int
    main()
    {
        using namespace std;
        using namespace std::chrono;
        const auto foo = 2018y;
        cout << int{foo} << '\n';
    }
    

    Outputs:

    2018
    

    Live demo that you can experiment with with the proviso that the "date.h" example implementation puts things in namespace date instead of namespace std::chrono.

    I should also note that this software allows for user-written calendars to interoperate with the std::chrono system. Here is an example of the Julian calendar. There are a couple more examples here.


    Finally, a brief note on the rationale as to why the current year is represented as year{2018} (Anno Domini), as opposed to year{48} (time_t's 1970 origin), or year{118} (tm_year's 1900 origin):

    This philosophy is hysterical when used in movies. But gets tiresome when used in software design. This library tries to do the expected.