The C and C++ standards say absolutely nothing about any calendar except the Gregorian calendar, and not a lot about that one.
1.
Months in a year
The only thing you'll find is a comment in the C standard beside the tm_mon
member of tm
:
int tm_mon; // months since January -- [0, 11]
Well, almost only. You'll also find %b
and %B
specifiers in strftime
which correspond to the current locale's abbreviated and full month names corresponding to tm_mon
.
2.
Days in a week
You've got:
int tm_wday; // days since Sunday -- [0, 6]
and %a
, %A
for strftime
.
3.
Hours in a day
You've got:
int tm_hour; // hours since midnight -- [0, 23]
There's also strftime
specifiers, a few of which are sensitive to the current locale.
4.
Minutes in an hour
int tm_min; // minutes after the hour -- [0, 59]
Also in this case you've got some help from the new C++11 <chrono>
library:
std::cout << std::chrono::hours{1}/std::chrono::minutes{1} << '\n';
This will portably (and consistently) output 60
. If your compiler supports constexpr
and you are worried about efficiency, this quantity can be a compile-time integral constant:
constexpr auto minutes_per_hour = std::chrono::hours{1}/std::chrono::minutes{1};
The type of minutes_per_hour
is guaranteed to be signed integral and at least 29 bits.
5.
Seconds in a minute
The C spec is a little interesting on this one:
int tm_sec; // seconds after the minutes -- [0, 60]
The range is not documented as [0, 59]
so as to allow for the addition of a positive leap second. That being said, no OS that I'm aware of actually implements an accurate accounting of leap seconds. Everyone appears to follow Unix Time which tracks UTC except ignoring leap seconds. When a leap second occurs, all OS's I'm aware of simply treat it as an ordinary clock correction. Google famously treats it as a smear of corrections over some window of time.
Additionally you can consistently and portably write:
std::cout << std::chrono::minutes{1}/std::chrono::seconds{1} << '\n';
and get 60
.
While not defined by the C or C++ standards, every OS appears to be measuring time since New Years 1970 (neglecting leap seconds). In C++11 this quantity is available via:
auto tp = std::chrono::system_clock::now();
where tp
will have type std::chrono::system_clock::time_point
. This time_point
has an unspecified precision (fortnights, seconds, femtoseconds, whatever). The precision is programmatically discoverable at compile time.
In case it is helpful, this link contains code which can translate tp
into year/month/day hour:minute:second and even fractions of a second (and vice-versa). Oh, day-of-week if you want it too (and several other calendrical tricks). This public domain code depends on the non-standard but de-facto portable epoch of New Years 1970. It could easily be adopted to other epochs if the need ever arises.