I propose though that DateTime("10000-01-01T00:00:00")
(or any higher) should fail by default (typemax, and typemin, would still be the same, at least for now(?)), while we could allow DateTime(10000)
to still work (and maybe keyword argument for the former? or not bother), which gets you the exact same, i.e. down to the millisecond, while only showing in microseconds.
C++ has all kinds of (chrono) types, some always integers, so always double (Float64); some a mix (template), i.e. of rationals and: std::chrono::duration - cppreference.com
If Rep is floating point, then the duration can represent fractions of ticks. […]
Member type |
Definition |
rep |
Rep, an arithmetic type representing the number of ticks |
period |
Period (until C++17)typename Period::type (since C++17), a std::ratio representing the tick period (i.e. the number of second’s fractions per tick) |
operator++
operator++(int)
operator== (C++11)
operator!= (C++11)(removed in C++20)
operator< (C++11)
[…]
operator<=> (C++20)
[Why removing inequality test (but not others)?]
std::chrono::nanoseconds duration</*signed integer type of at least 64 bits*/, std::nano>
std::chrono::microseconds duration</*signed integer type of at least 55 bits*/, std::micro>
..
std::chrono::milliseconds duration</*signed integer type of at least 45 bits*/, std::milli>
..
std::chrono::days (since C++20) duration</*signed integer type of at least 25 bits*/, std::ratio<86400>>
..
std::chrono::years (since C++20) duration</*signed integer type of at least 17 bits*/, std::ratio<31556952>>
std::chrono::duration not to be confused with std::difftime - cppreference.com which is always a double (Float64).
https://www.isotc154.org/posts/2019-08-27-introduction-to-the-new-8601/
Here’s a short history of ISO 8601.
Predecessors:
ISO 2014:1976 (all-numeric dates)
ISO 2015:1976 (week numbering)
ISO 2711:1973 (ordinal date numbering)
ISO 3307:1975 (representations of time of the day)
ISO 4031:1978 (time differentials)
These standards were all superseded by the first ISO 8601, ISO 8601:1988.
I was seemingly wrong on “time differentials” not in the standard (in ISO 8601, which we support, I’m not clear on what C++ is trying to support). We don’t specifically state which part of ISO 8601 we do support, or do NOT support, but even if we do not support that (or some specific) part, or do incorrectly, then I suppose we need to support, and change if needed to, what the standard says on it.
Do we support them correctly (through compatibility with the old ISO 4031:1978, we never supported most of above, e.g. I don’t think currently “week numbering”, but likely should). Note, latest ISO 8601 has been 80% rewritten, so I’m not sure what it says on it (currently).
[I found it somewhat intriguing that Julia deprecates Libc.TimeVal, but then uses it for `now()`.]
We seemingly need equivalent of timespec_get (std::timespec - cppreference.com (both “since C++17”))
Possible output:
Current time: 06/24/16 20:07:42.949494132 UTC
std::time_t tv_sec |
whole seconds – >= 0 |
[Is that in error? does it allow unsigned as it used to, or now unsigned since 64-bit?] |
long tv_nsec |
nanoseconds – [0, 999999999] |
|
Current time: 04/06/23 12:03:31 (UTC)
Raw timespec.time_t: 1680782611
Raw timespec.tv_nsec: 678437213
so it’s a struct of, the latter, long
, i.e. at least 32 bits (and in practice can be long long
), and the former an unspecified type, but usually 64-bit integer, so 128 bits.
timespec_get (C++17)
returns the calendar time in seconds and nanoseconds based on a given time base (function)
[You can have only 584 years of nanosecond resolution in Int64. Since other languages have that resolution, and that seems useful, sometimes, why isn’t time limited to that many years? Already we can’t reach big bang, and if I were doing this I would choose that or from 3000 BC to 2840 in resolution of 10s of nanoseconds? I’m also partial to a rational form, 63 bits for the nominator in nanoseconds, and to reach big-bang, and far into the future, if the last bit is 1, then the the denominator is huge, making the resolution in 10s of seconds. Who cares about the extremes? Or just go to Float32?]
Certainly oddities (that I bolded): ISO week date - Wikipedia
An ISO week-numbering year (also called ISO year informally) has 52 or 53 full weeks. That is 364 or 371 days instead of the usual 365 or 366 days. […] The extra week is sometimes referred to as a leap week, although ISO 8601 does not use this term.
And mostly more trivia below:
std::chrono::treat_as_floating_point (since C++11)
Data Type: time_t
time_t is the simplest data type used to represent simple calendar time.
In ISO C, time_t can be either an integer or a floating-point type, and the meaning of time_t values is not specified. The only things a strictly conforming program can do with time_t values are: pass them to difftime to get the elapsed time between two simple calendar times (see Calculating Elapsed Time), and pass them to the functions that convert them to broken-down time (see Broken-down Time).
On POSIX-conformant systems, time_t is an integer type and its values represent the number of seconds elapsed since the epoch, which is 00:00:00 on January 1, 1970, Coordinated Universal Time.
The GNU C Library additionally guarantees that time_t is a signed type, and that all of its functions operate correctly on negative time_t values, which are interpreted as times before the epoch.Even though time_t is usually not a float, there is:
double difftime( std::time_t time_end, std::time_t time_beg );
Computes difference between two calendar times as std::time_t objects (time_end - time_beg) in seconds. If time_end refers to time point before time_beg then the result is negative.
std::clock time may advance faster or slower than the wall clock, depending on the execution resources given to the program by the operating system. For example, if the CPU is shared by other processes, std::clock time may advance slower than wall clock. On the other hand, if the current process is multithreaded and more than one execution core is available, std::clock time may advance faster than wall clock. […]
On POSIX-compatible systems, clock_gettime with clock id CLOCK_PROCESS_CPUTIME_ID offers better resolution.
The value returned by clock() may wrap around on some non-conforming implementations.
clock_t is used to measure processor and CPU time. It may be an integer or a floating-point type. Its values are counts of clock ticks since some arbitrary event in the past. The number of clock ticks per second is system-specific. See Processor And CPU Time, for further detail.
https://en.cppreference.com/w/cpp/numeric/ratio/ratio
quecto (C++26) |
std::ratio<1, 1000000000000000000000000000000> (10-30), if std::intmax_t can represent the denominator |
ronto (C++26) |
std::ratio<1, 1000000000000000000000000000> (10-27), if std::intmax_t can represent the denominator |
yocto |
std::ratio<1, 1000000000000000000000000> (10-24), if std::intmax_t can represent the denominator |
… |
|
ronna (C++26) |
std::ratio<1000000000000000000000000000, 1> (1027), if std::intmax_t can represent the numerator |
quetta (C++26) |
std::ratio<1000000000000000000000000000000, 1> (1030), if std::intmax_t can represent the numerator |