Reputation: 1018
Does C++ stl have a standard time class? Or do I have to convert to c-string before writing to a stream. Example, I want to output the current date/time to a string stream:
time_t tm(); ostringstream sout; sout << tm << ends;
In this case I get the current date/time written out as a number without any formatting. I can use
c- runtime function strftime
to format tm first, but that seems like it should not be necessary if the stl has a time class that can be instantiated from time_t value
Upvotes: 38
Views: 87180
Reputation: 218710
Well, it's been a dozen years since this question was asked. And now (in C++20) it finally has a better answer.
Yes, there are several standard date/time classes in C++20 (not just one). Each serves different purposes in a strongly typed system. For example std::chrono::zoned_time
represents a pairing of a std::chrono::time_zone
and a std::chrono::time_point<system_clock, SomeDuration>
, and represents the local time in some geographic area. Here is how you might create and print the local time in your current time zone to the finest sub-second precision your OS allows.
cout << zoned_time{current_zone(), system_clock::now()} << '\n';
If you need the local time somewhere else, that is just as easily obtained:
cout << zoned_time{"Africa/Casablanca", system_clock::now()} << '\n';
Unlike in previous C++ standards, time_point
s based on system_clock
are now guaranteed to represent UTC, neglecting leap seconds (aka Unix Time). So to get the current time in UTC it is simply:
cout << system_clock::now() << '\n';
Though if you really wanted to use a zoned_time
instead (for example the code may be generic), this also works:
cout << zoned_time{"UTC", system_clock::now()} << '\n';
See https://en.cppreference.com/w/cpp/chrono for many more standard date/time classes. All of them are thread-safe. And you are no longer limited to seconds precision.
Let's say you wanted to print out your local time 24 hours ago.
Well the first thing is to decide if you mean 24 physical hours, or you want the same time-of-day yesterday as it is now according to your local clock. These two things are almost always the same. But if you've experienced going onto, or coming off of daylight saving in the last 24 hours, they're different.
C++20 chrono can do both, and it is quite easy either way:
A. This is how you compute exactly 24 physical hours before now:
auto timeNow = system_clock::now();
auto timeYesterday = current_zone()->to_local(timeNow - 24h);
std::cout << "24 hours ago, the local time was " << timeYesterday << '\n';
B. If you instead want the date/time which has the same local time yesterday as the local time is now, that is a very slight adjustment to the above code:
auto timeYesterday = current_zone()->to_local(timeNow) - 24h;
As stated before, these two algorithms nearly always give the same result. But every once in a while, and for some time zones, they can give different answers. So it is good to know what you want, and have the flexibility to easily program what you want. And to have the code reflect your decision when other programmers are reading it.
Finally, instead of subtracting 24h
, one could also use days{1}
or 86'400s
, or any other unit which indicates the desired passage of time. The only difference is readability.
Upvotes: 6
Reputation: 11
This thread started with the question for "a time class that can be instanciated from time_t value". I searched for the same and looked at "chrono". Until now I cannot say if there is one object representing the time. There is 'system_clock', 'steady_clock', 'clock_time_conversion', 'zoned_time', ... Well, this was by far too confusing for me and I doubt Farid Z searched for such a complex world of classes. The following example to calculate the date 24 hours after now was given:
using namespace std::literals; // enables literal suffixes, e.g. 24h, 1ms, 1s.
const std::chrono::time_point<std::chrono::system_clock> now =
std::chrono::system_clock::now();
const std::time_t t_c = std::chrono::system_clock::to_time_t(now - 24h);
std::cout << "24 hours ago, the time was "
<< std::put_time(std::localtime(&t_c), "%F %T.\n") << std::flush;
24 hours ago, the time was 2021-02-15 18:28:52.
Is this the solution for a simplified usage of time? I sympathized with 'mkluwe' who stated: "If wrapping (or simply using) these functions [ctime] is sufficient (and quicker) than pulling in boost, go with these. There is nothing wrong with them.". Yes, but where to find a C++ class representing time and wrapping those 'ctime' functions? I did not succeed in finding such a class. Therefore I took some time to do so and maybe someone is happy finding it now. The class is named 'cTime' in the namespace 'LibCpp'.
using namespace LibCpp;
cTime timeNow = cTime::now();
stDuration duration24 = stDuration_Ini;
duration24.hours = 24;
cTime duration = cTime::set(duration24);
cTime timeTomorrow = timeNow + duration;
printf("24 hours ago, the time was %s", timeTomorrow.toString().c_str());
See https://github.com/OlafSimon/cTime in case of interest in this class 'cTime' representing Unix time and wrapping 'ctime' functions. And yes, you can instanciate from a 'time_t' variable e.g. named 'myTimeT'.
cTime myTime = cTime::set(myTimeT);
Upvotes: 0
Reputation: 4061
EDIT
The standard "datetime" class is std::chrono::time_point
since C++11. The code in the question should be roughly equivalent to
const auto now = std::chrono::system_clock::now();
const auto t_c = std::chrono::system_clock::to_time_t(now);
std::cout << std::put_time(std::localtime(&t_c), "%F %T.\n");
OLD ANSWER
Nitpicking: The STL being the Standard Template Library deals with generic container and algorithms etc. and is unlikely to incorporate classes for date handling and calculation even in the future…
The C++ Standard Library itself includes the STL and a previous version of the C standard library. The latter offers some date and time related functions via #include <ctime>
which has already been mentioned above.
If wrapping (or simply using) these functions is sufficient (and quicker) than pulling in boost, go with these. There is nothing wrong with them.
Upvotes: 22
Reputation:
C++ now has the chrono libraries for date and time. This is documented on http://en.cppreference.com/w/cpp/chrono and http://www.cplusplus.com/reference/chrono/
Upvotes: 10
Reputation: 19928
Not part of STL but well known library is boost.
I would go the way of using boost::date
. Here are some examples: http://www.boost.org/doc/libs/1_55_0/doc/html/date_time/date_time_io.html#date_time.io_tutorial.
If you did not try out boost yet I encourage you to do so as it saves you from a lot of nasty issues, as it masks most OS dependent things like threading for example. Many things in boost
are header only (template libraries). However datetime requires a lib or dll.
Upvotes: 26
Reputation: 1432
There are get_time and put_time in <iomanip> header (i guess these came with C++11) which effectively does string formatting or parsing jobs.
Upvotes: 6
Reputation: 1018
OK. Here is closest I have found about directly writing time to a stream:
time_t t(time(NULL)); // current time
tm tm(*localtime(&t));
std::locale loc(""); // current user locale
ostringstream sout;
const std::time_put<TCHAR> &tput =
std::use_facet<std::time_put<TCHAR> >(loc);
tput.put(sout.rdbuf(), sout, _T('\0'), &tm, _T('x'));
sout << ends;
CString sTest(sout.str().c_str());
A very helpful guide is the Apache C++ Standard Library Reference Guide http://stdcxx.apache.org/doc/stdlibref/time-put.html#sec13
Upvotes: 4