I'm trying to figure out how to use std::chrono
to create and manipulate a datetime type.
In particular, I need some kind of type to store a datetime type. The input and output of my program will be JSON formatted data. JSON is used for data serialization when sending and receiving data from a network.
JSON does not support datetime types, however it does support strings.
The tl;dr for this is that I need some type or structure which can store a datetime type, and I need to be able to convert between that type and a std::string
type.
For this question to be coherent I need to provide a bit of context.
To review the situation:
- I am working on a Linux system. Linux supports two kinds of clocks. There is the
CLOCK_REALTIME
, and theCLOCK_MONOTONIC
. (There are others in addition to this, but these are the interesting ones.) The clock can be accessed by calling theclock_gettime
function. This talks to the OS, and returns the clock value for the chosen type of clock. - C++ provides
std::chrono
which has different kinds of clocks. I'm not sure exactly how these map to the underlying Linux clocks. I would guess thatstd::chrono::system_time
is aCLOCK_REALTIME
, andstd::chrono::steady_clock
is aCLOCK_MONOTONIC
. - There are other types of clock in
std::chrono
. I don't know what they map to. Maybe some of them don't map to anyclock_gettime
function at all. - Since C++ and
std::chrono
is cross platform, it is presumably the case that other Operating Systems provide similar types of clock to those provided by Linux. I don't expect the implementation of the clocks contained withinstd::chrono
to behave the same way on different platforms. Some platforms might only have a single type of "clock get time" function, for example. - For some (all?) of the clock types within
std::chrono
, there is a::now()
function, which returns the current time, using whichever is the relevant underlying implementation. - Put another way, a
now()
function is thestd::chrono
library equivalent of the lower levelclock_gettime
function. (Or whatever is the equivalent for other platforms. eg: Windows will have some other function, it is probably not calledclock_gettime
.)
Here's where my confusion starts.
- What kind of
std::chrono
clock can I use if I don't need something which is attached to a particular implementation of aclock_gettime
function?
To phrase this in a different way
- Does
std::chrono
have a clock type which does not have anow()
implementation?
To go back to the first few paragraphs in this question, I want to write some code which converts a string representation of a datetime into some C++ type.
For example
2025-02-09T15:39:00.123456789+0000 // example
I think the way to do it is to convert this string into a std::chrono::time_point
.
However, a time_point
is a templated class, which required some kind of class Clock
to be specified.
- See here:
It doesn't seem to make much sense to use steady_clock
or system_clock
here, since both of those are connected to a particular implementation of a now()
function, with an underlying clock_gettime
implementation.
Put another way, if I were to use one of these options, there doesn't seem to be a sensible way to choose between them.
Have I understood everything correctly here? I'm wondering if perhaps I have misunderstood something and perhaps this is the source of my confusion.
I'm trying to figure out how to use std::chrono
to create and manipulate a datetime type.
In particular, I need some kind of type to store a datetime type. The input and output of my program will be JSON formatted data. JSON is used for data serialization when sending and receiving data from a network.
JSON does not support datetime types, however it does support strings.
The tl;dr for this is that I need some type or structure which can store a datetime type, and I need to be able to convert between that type and a std::string
type.
For this question to be coherent I need to provide a bit of context.
To review the situation:
- I am working on a Linux system. Linux supports two kinds of clocks. There is the
CLOCK_REALTIME
, and theCLOCK_MONOTONIC
. (There are others in addition to this, but these are the interesting ones.) The clock can be accessed by calling theclock_gettime
function. This talks to the OS, and returns the clock value for the chosen type of clock. - C++ provides
std::chrono
which has different kinds of clocks. I'm not sure exactly how these map to the underlying Linux clocks. I would guess thatstd::chrono::system_time
is aCLOCK_REALTIME
, andstd::chrono::steady_clock
is aCLOCK_MONOTONIC
. - There are other types of clock in
std::chrono
. I don't know what they map to. Maybe some of them don't map to anyclock_gettime
function at all. - Since C++ and
std::chrono
is cross platform, it is presumably the case that other Operating Systems provide similar types of clock to those provided by Linux. I don't expect the implementation of the clocks contained withinstd::chrono
to behave the same way on different platforms. Some platforms might only have a single type of "clock get time" function, for example. - For some (all?) of the clock types within
std::chrono
, there is a::now()
function, which returns the current time, using whichever is the relevant underlying implementation. - Put another way, a
now()
function is thestd::chrono
library equivalent of the lower levelclock_gettime
function. (Or whatever is the equivalent for other platforms. eg: Windows will have some other function, it is probably not calledclock_gettime
.)
Here's where my confusion starts.
- What kind of
std::chrono
clock can I use if I don't need something which is attached to a particular implementation of aclock_gettime
function?
To phrase this in a different way
- Does
std::chrono
have a clock type which does not have anow()
implementation?
To go back to the first few paragraphs in this question, I want to write some code which converts a string representation of a datetime into some C++ type.
For example
2025-02-09T15:39:00.123456789+0000 // example
I think the way to do it is to convert this string into a std::chrono::time_point
.
However, a time_point
is a templated class, which required some kind of class Clock
to be specified.
- See here: https://en.cppreference.com/w/cpp/chrono/time_point
It doesn't seem to make much sense to use steady_clock
or system_clock
here, since both of those are connected to a particular implementation of a now()
function, with an underlying clock_gettime
implementation.
Put another way, if I were to use one of these options, there doesn't seem to be a sensible way to choose between them.
Have I understood everything correctly here? I'm wondering if perhaps I have misunderstood something and perhaps this is the source of my confusion.
Share Improve this question asked yesterday user2138149user2138149 16.8k30 gold badges145 silver badges287 bronze badges 4 |1 Answer
Reset to default 1There are lots of good questions here. I'll try to answer all of them:
Is it possible to use std::chrono to create a datetime type which is not linked to a particular clock or implementation of a "now" function?
Yes. For example you could create your own clock type which does nothing, and does not contain a now()
function. That might look like this:
struct no_clock {};
template<class Duration>
using clock_less_time = time_point<no_clock, Duration>;
Now you can say: clock_less_time t{};
and t
is a chrono::time_point
based on no_clock
. And if you try to say: decltype(t)::clock::now()
, you will get a compile-time error because that statement attempts to call no_clock::now()
.
C++ provides std::chrono which has different kinds of clocks. I'm not sure exactly how these map to the underlying Linux clocks. I would guess that std::chrono::system_time is a CLOCK_REALTIME, and std::chrono::steady_clock is a CLOCK_MONOTONIC.
That is correct.
Does std::chrono have a clock type which does not have a now() implementation?
Yes: std::chrono::local_t
. local_t
is an empty struct
just like the no_clock
example above. There also exists a local_time
templated type alias to help make time_point
s with that clock:
template<class Duration>
using local_time = time_point<local_t, Duration>;
And you could use local_time
for your purposes if you wanted. That would be especially appropriate if you strings represented local time of a possibly yet to be specified time zone.
For example
2025-02-09T15:39:00.123456789+0000 // example
I think the way to do it is to convert this string into a
std::chrono::time_point
.
Now I'm a little confused. This string represents a point in time in UTC, or if the time zone offset were non-zero, a local time in the time zone with said non-zero offset.
There are two ways to parse this:
- As
sys_time
(time_point
based onsystem_clock
). The definition of these time points is that they represent UTC (as doesCLOCK_REALTIME
).
If you parse as a sys_time
, and the offset is non-zero, it will subtract the offset from the parsed local time to produce the sys_time
. Example code:
istringstream in{"2025-02-09T15:39:00.123456789+0000"};
sys_time<nanoseconds> tp;
in >> parse("%FT%T%z", tp);
// tp now has the value 2025-02-09 15:39:00.123456789 UTC
- As
local_time
. If you parse intolocal_time
you get the exact value of thestring
without taking theoffset
into account. You have the option of saving the parsed value of the offset, or throwing it away. Either way, the offset does not alter the local time parsed.
The second option would look like:
istringstream in{"2025-02-09T15:39:00.123456789+0000"};
local_time<nanoseconds> tp;
in >> parse("%FT%T%z", tp);
// tp now has the value 2025-02-09 15:39:00.123456789
If you wanted to save the offset, that would look like:
istringstream in{"2025-02-09T15:39:00.123456789+0000"};
local_time<nanoseconds> tp;
minutes offset;
in >> parse("%FT%T%z", tp, offset);
// tp now has the value 2025-02-09 15:39:00.123456789
// offset has the value 0min
time_point
tied to a clock?time_point
is just a number, without a clock that number is fairly meaningless. If all you want to do is convert a date time from a string representation and back again thensystem_clock
is exactly what you want, it'll behave similarly on all platforms, that's the whole point of the standard library – Alan Birtles Commented yesterdaynow
function, and this is really one of the core reasons to use the type. The point of asystem_clock
or asteady_clock
is to be able to get a value representing the current time using::now()
. To use them for some other primary purpose just feels a bit strange. – user2138149 Commented 20 hours agotime_t
and related functions? That gives you a time point you can convert but it can be any value you like.. – Rud48 Commented 19 hours agotime_t
to store a time, that has anow
function too. If you don't want to get the current time, just don't callnow
, it being part of the clock doesn't do you any harm – Alan Birtles Commented 12 hours ago