Current date and time as string - c++

I wrote a function to get a current date and time in format: DD-MM-YYYY HH:MM:SS. It works but let's say, its pretty ugly. How can I do exactly the same thing but simpler?
string currentDateToString()
{
time_t now = time(0);
tm *ltm = localtime(&now);
string dateString = "", tmp = "";
tmp = numToString(ltm->tm_mday);
if (tmp.length() == 1)
tmp.insert(0, "0");
dateString += tmp;
dateString += "-";
tmp = numToString(1 + ltm->tm_mon);
if (tmp.length() == 1)
tmp.insert(0, "0");
dateString += tmp;
dateString += "-";
tmp = numToString(1900 + ltm->tm_year);
dateString += tmp;
dateString += " ";
tmp = numToString(ltm->tm_hour);
if (tmp.length() == 1)
tmp.insert(0, "0");
dateString += tmp;
dateString += ":";
tmp = numToString(1 + ltm->tm_min);
if (tmp.length() == 1)
tmp.insert(0, "0");
dateString += tmp;
dateString += ":";
tmp = numToString(1 + ltm->tm_sec);
if (tmp.length() == 1)
tmp.insert(0, "0");
dateString += tmp;
return dateString;
}

Since C++11 you could use std::put_time from iomanip header:
#include <iostream>
#include <iomanip>
#include <ctime>
int main()
{
auto t = std::time(nullptr);
auto tm = *std::localtime(&t);
std::cout << std::put_time(&tm, "%d-%m-%Y %H-%M-%S") << std::endl;
}
std::put_time is a stream manipulator, therefore it could be used together with std::ostringstream in order to convert the date to a string:
#include <iostream>
#include <iomanip>
#include <ctime>
#include <sstream>
int main()
{
auto t = std::time(nullptr);
auto tm = *std::localtime(&t);
std::ostringstream oss;
oss << std::put_time(&tm, "%d-%m-%Y %H-%M-%S");
auto str = oss.str();
std::cout << str << std::endl;
}

Non C++11 solution: With the <ctime> header, you could use strftime. Make sure your buffer is large enough, you wouldn't want to overrun it and wreak havoc later.
#include <iostream>
#include <ctime>
int main ()
{
time_t rawtime;
struct tm * timeinfo;
char buffer[80];
time (&rawtime);
timeinfo = localtime(&rawtime);
strftime(buffer,sizeof(buffer),"%d-%m-%Y %H:%M:%S",timeinfo);
std::string str(buffer);
std::cout << str;
return 0;
}

you can use asctime() function of time.h to get a string simply .
time_t _tm =time(NULL );
struct tm * curtime = localtime ( &_tm );
cout<<"The current date/time is:"<<asctime(curtime);
Sample output:
The current date/time is:Fri Oct 16 13:37:30 2015

With C++20, time point formatting (to string) is available in the (chrono) standard library.
https://en.cppreference.com/w/cpp/chrono/system_clock/formatter
#include <chrono>
#include <format>
#include <iostream>
int main()
{
const auto now = std::chrono::system_clock::now();
std::cout << std::format("{:%d-%m-%Y %H:%M:%OS}", now) << '\n';
}
Output
13-12-2021 09:24:44
It works in Visual Studio 2019 (v16.11.5) with the latest C++ language version (/std:c++latest).

Using C++ in MS Visual Studio 2015 (14), I use:
#include <chrono>
string NowToString()
{
chrono::system_clock::time_point p = chrono::system_clock::now();
time_t t = chrono::system_clock::to_time_t(p);
char str[26];
ctime_s(str, sizeof str, &t);
return str;
}

#include <chrono>
#include <iostream>
int main()
{
std::time_t ct = std::time(0);
char* cc = ctime(&ct);
std::cout << cc << std::endl;
return 0;
}

I wanted to use the C++11 answer, but I could not because GCC 4.9 does not support std::put_time.
std::put_time implementation status in GCC?
I ended up using some C++11 to slightly improve the non-C++11 answer. For those that can't use GCC 5, but would still like some C++11 in their date/time format:
std::array<char, 64> buffer;
buffer.fill(0);
time_t rawtime;
time(&rawtime);
const auto timeinfo = localtime(&rawtime);
strftime(buffer.data(), sizeof(buffer), "%d-%m-%Y %H-%M-%S", timeinfo);
std::string timeStr(buffer.data());

Related

Calculate time difference using c++

I have a chunk of code where I am trying to convert the string time into time_t and then use the difftime() method to do a comparison. However, currently, the difftime returns 0 instead of the number of seconds differences. Can someone help me on this please.
Here's my C++ code:
const char *time_details = "16:35:12";
const char *another_time = "18:35:15";
struct tm tm = { 0 };
struct tm tm1 = { 0 };
istringstream ss(time_details);
istringstream ss1(another_time);
ss >> get_time(&tm, "%H:%M:%S"); // or just %T in this case
ss1 >> get_time(&tm1, "%H:%M:%S");
std::time_t time1 = mktime(&tm);
std::time_t time2 = mktime(&tm1);
double a = difftime(time2, time1);
cout << "the diff is : " << a;
I am following this stackoverflow solution as my reference. Really appreciate your helps on this one.
Maybe your compiler version is too low.I have no problem compiling the following code in g++ 9.
#include <ctime>
#include <sstream>
#include <iomanip>
#include <time.h>
#include <iostream>
using namespace std;
int main()
{
const char *time_details = "16:35:12";
const char *another_time = "18:35:15";
struct tm tm = { 0 };
struct tm tm1 = { 0 };
istringstream ss(time_details);
istringstream ss1(another_time);
ss >> get_time(&tm, "%H:%M:%S"); // or just %T in this case
ss1 >> get_time(&tm1, "%H:%M:%S");
std::time_t time1 = mktime(&tm);
std::time_t time2 = mktime(&tm1);
double a = difftime(time2, time1);
cout << "the diff is : " << a;
return 0;
}
The output is the diff is : 7203

How to convert a "%Y%m%d" format string into a time_t variable in C++?

I'm trying to convert strings into time_t variables. Here's the code I tried:
#include "pch.h"
#include <ctime>
#include <iomanip>
#include <iostream>
#include <sstream>
using namespace std;
time_t String_to_timet1(string endDate) {
tm tm = { 0 };
stringstream ss(endDate);
ss >> get_time(&tm, "%Y-%m-%d %H:%M:%S");
time_t epoch = mktime(&tm);
return epoch;
}
time_t String_to_timet2(string endDate) {
tm tm = { 0 };
stringstream ss(endDate);
ss >> get_time(&tm, "%Y%m%d");
time_t epoch = mktime(&tm);
return epoch;
}
int main()
{
time_t time_certainTime1 = String_to_timet1("2019-01-01 00:00:00");
cout << time_certainTime1 << endl;
time_t time_certainTime2 = String_to_timet2("20190101");
cout << time_certainTime2 << endl;
return 0;
}
I expected that the results would be the same, but when I run the code with Visual Studio 2017, the results are:
1546268400
-1
and when I run the same code on https://www.onlinegdb.com/online_c++_compiler, the results are:
1546300800
1546300800
Question: Why does Visual Studio give me -1 when it gets a "%Y%m%d" typed string (when the online compiler gives me the result I expected)? How to make a time_t variable with such format?
In the documentation for both %m and %d it says leading zeros permitted but not required. This means that it's actually underspecified if it will work without separators or not.

How to change the format of date and time with time_t?

time_t now = time(0);
std::string h = std::string (ctime (&now));
std::cout << "\nh: " << h;
Current output that I am receiving is: Thu Sep 14 10:58:26 2017
I want the output as 2017-08-26-16-10-56
What can I do to that output?
Use strftime, like this:
strftime (buffer, 80,"%Y-%m-%d-%H-%M-%S",timeinfo);
Full code:
#include <cstdio>
#include <ctime>
int main ()
{
time_t rawtime;
struct tm * timeinfo;
char buffer [80];
time (&rawtime);
timeinfo = localtime (&rawtime);
strftime (buffer, 80,"%Y-%m-%d-%H-%M-%S",timeinfo);
puts (buffer);
return 0;
}
Output:
2017-09-14-14-41-19
Use std::put_time
#include <iomanip>
time_t now = time(0);
std::string h = std::put_time(localtime(&now), "%F-%H-%M-%S");
std::cout << "\nh: " << h;
Output
h: 2017-09-14-05-54-02
Even better, use std::chrono
#include <iostream>
#include <iomanip>
#include <chrono>
using namespace std;
int main() {
auto now = chrono::system_clock::to_time_t(chrono::system_clock::now());
cout << put_time(localtime(&now), "%F-%H-%M-%S") << endl;
return 0;
}

How to convert std::chrono::time_point to calendar datetime string with fractional seconds?

How to convert std::chrono::time_point to calendar datetime string with fractional seconds?
For example:
"10-10-2012 12:38:40.123456"
If system_clock, this class have time_t conversion.
#include <iostream>
#include <chrono>
#include <ctime>
using namespace std::chrono;
int main()
{
system_clock::time_point p = system_clock::now();
std::time_t t = system_clock::to_time_t(p);
std::cout << std::ctime(&t) << std::endl; // for example : Tue Sep 27 14:21:13 2011
}
example result:
Thu Oct 11 19:10:24 2012
EDIT:
But, time_t does not contain fractional seconds.
Alternative way is to use time_point::time_since_epoch() function. This function returns duration from epoch.
Follow example is milli second resolution's fractional.
#include <iostream>
#include <chrono>
#include <ctime>
using namespace std::chrono;
int main()
{
high_resolution_clock::time_point p = high_resolution_clock::now();
milliseconds ms = duration_cast<milliseconds>(p.time_since_epoch());
seconds s = duration_cast<seconds>(ms);
std::time_t t = s.count();
std::size_t fractional_seconds = ms.count() % 1000;
std::cout << std::ctime(&t) << std::endl;
std::cout << fractional_seconds << std::endl;
}
example result:
Thu Oct 11 19:10:24 2012
925
Self-explanatory code follows which first creates a std::tm corresponding to 10-10-2012 12:38:40, converts that to a std::chrono::system_clock::time_point, adds 0.123456 seconds, and then prints that out by converting back to a std::tm. How to handle the fractional seconds is in the very last step.
#include <iostream>
#include <chrono>
#include <ctime>
int main()
{
// Create 10-10-2012 12:38:40 UTC as a std::tm
std::tm tm = {0};
tm.tm_sec = 40;
tm.tm_min = 38;
tm.tm_hour = 12;
tm.tm_mday = 10;
tm.tm_mon = 9;
tm.tm_year = 112;
tm.tm_isdst = -1;
// Convert std::tm to std::time_t (popular extension)
std::time_t tt = timegm(&tm);
// Convert std::time_t to std::chrono::system_clock::time_point
std::chrono::system_clock::time_point tp =
std::chrono::system_clock::from_time_t(tt);
// Add 0.123456 seconds
// This will not compile if std::chrono::system_clock::time_point has
// courser resolution than microseconds
tp += std::chrono::microseconds(123456);
// Now output tp
// Convert std::chrono::system_clock::time_point to std::time_t
tt = std::chrono::system_clock::to_time_t(tp);
// Convert std::time_t to std::tm (popular extension)
tm = std::tm{0};
gmtime_r(&tt, &tm);
// Output month
std::cout << tm.tm_mon + 1 << '-';
// Output day
std::cout << tm.tm_mday << '-';
// Output year
std::cout << tm.tm_year+1900 << ' ';
// Output hour
if (tm.tm_hour <= 9)
std::cout << '0';
std::cout << tm.tm_hour << ':';
// Output minute
if (tm.tm_min <= 9)
std::cout << '0';
std::cout << tm.tm_min << ':';
// Output seconds with fraction
// This is the heart of the question/answer.
// First create a double-based second
std::chrono::duration<double> sec = tp -
std::chrono::system_clock::from_time_t(tt) +
std::chrono::seconds(tm.tm_sec);
// Then print out that double using whatever format you prefer.
if (sec.count() < 10)
std::cout << '0';
std::cout << std::fixed << sec.count() << '\n';
}
For me this outputs:
10-10-2012 12:38:40.123456
Your std::chrono::system_clock::time_point may or may not be precise enough to hold microseconds.
Update
An easier way is to just use this date library. The code simplifies down to (using C++14 duration literals):
#include "date.h"
#include <iostream>
#include <type_traits>
int
main()
{
using namespace date;
using namespace std::chrono;
auto t = sys_days{10_d/10/2012} + 12h + 38min + 40s + 123456us;
static_assert(std::is_same<decltype(t),
time_point<system_clock, microseconds>>{}, "");
std::cout << t << '\n';
}
which outputs:
2012-10-10 12:38:40.123456
You can skip the static_assert if you don't need to prove that the type of t is a std::chrono::time_point.
If the output isn't to your liking, for example you would really like dd-mm-yyyy ordering, you could:
#include "date.h"
#include <iomanip>
#include <iostream>
int
main()
{
using namespace date;
using namespace std::chrono;
using namespace std;
auto t = sys_days{10_d/10/2012} + 12h + 38min + 40s + 123456us;
auto dp = floor<days>(t);
auto time = make_time(t-dp);
auto ymd = year_month_day{dp};
cout.fill('0');
cout << ymd.day() << '-' << setw(2) << static_cast<unsigned>(ymd.month())
<< '-' << ymd.year() << ' ' << time << '\n';
}
which gives exactly the requested output:
10-10-2012 12:38:40.123456
Update
Here is how to neatly format the current time UTC with milliseconds precision:
#include "date.h"
#include <iostream>
int
main()
{
using namespace std::chrono;
std::cout << date::format("%F %T\n", time_point_cast<milliseconds>(system_clock::now()));
}
which just output for me:
2016-10-17 16:36:02.975
C++17 will allow you to replace time_point_cast<milliseconds> with floor<milliseconds>. Until then date::floor is available in "date.h".
std::cout << date::format("%F %T\n", date::floor<milliseconds>(system_clock::now()));
Update C++20
In C++20 this is now simply:
#include <chrono>
#include <iostream>
int
main()
{
using namespace std::chrono;
auto t = sys_days{10d/10/2012} + 12h + 38min + 40s + 123456us;
std::cout << t << '\n';
}
Or just:
std::cout << std::chrono::system_clock::now() << '\n';
std::format will be available to customize the output.
In general, you can't do this in any straightforward fashion. time_point is essentially just a duration from a clock-specific epoch.
If you have a std::chrono::system_clock::time_point, then you can use std::chrono::system_clock::to_time_t to convert the time_point to a time_t, and then use the normal C functions such as ctime or strftime to format it.
Example code:
std::chrono::system_clock::time_point tp = std::chrono::system_clock::now();
std::time_t time = std::chrono::system_clock::to_time_t(tp);
std::tm timetm = *std::localtime(&time);
std::cout << "output : " << std::put_time(&timetm, "%c %Z") << "+"
<< std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch()).count() % 1000 << std::endl;
This worked for me for a format like YYYY.MM.DD-HH.MM.SS.fff. Attempting to make this code capable of accepting any string format will be like reinventing the wheel (i.e. there are functions for all this in Boost.
std::chrono::system_clock::time_point string_to_time_point(const std::string &str)
{
using namespace std;
using namespace std::chrono;
int yyyy, mm, dd, HH, MM, SS, fff;
char scanf_format[] = "%4d.%2d.%2d-%2d.%2d.%2d.%3d";
sscanf(str.c_str(), scanf_format, &yyyy, &mm, &dd, &HH, &MM, &SS, &fff);
tm ttm = tm();
ttm.tm_year = yyyy - 1900; // Year since 1900
ttm.tm_mon = mm - 1; // Month since January
ttm.tm_mday = dd; // Day of the month [1-31]
ttm.tm_hour = HH; // Hour of the day [00-23]
ttm.tm_min = MM;
ttm.tm_sec = SS;
time_t ttime_t = mktime(&ttm);
system_clock::time_point time_point_result = std::chrono::system_clock::from_time_t(ttime_t);
time_point_result += std::chrono::milliseconds(fff);
return time_point_result;
}
std::string time_point_to_string(std::chrono::system_clock::time_point &tp)
{
using namespace std;
using namespace std::chrono;
auto ttime_t = system_clock::to_time_t(tp);
auto tp_sec = system_clock::from_time_t(ttime_t);
milliseconds ms = duration_cast<milliseconds>(tp - tp_sec);
std::tm * ttm = localtime(&ttime_t);
char date_time_format[] = "%Y.%m.%d-%H.%M.%S";
char time_str[] = "yyyy.mm.dd.HH-MM.SS.fff";
strftime(time_str, strlen(time_str), date_time_format, ttm);
string result(time_str);
result.append(".");
result.append(to_string(ms.count()));
return result;
}
I would have put this in a comment on the accepted answer, since that's where it belongs, but I can't. So, just in case anyone gets unreliable results, this could be why.
Be careful of the accepted answer, it fails if the time_point is before the epoch.
This line of code:
std::size_t fractional_seconds = ms.count() % 1000;
will yield unexpected values if ms.count() is negative (since size_t is not meant to hold negative values).
In my case I use chrono and c function localtime_r which is thread-safe (in opposition to std::localtime).
#include <iostream>
#include <chrono>
#include <ctime>
#include <time.h>
#include <iomanip>
int main() {
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
std::chrono::milliseconds now2 = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
struct tm currentLocalTime;
localtime_r(&currentTime, &currentLocalTime);
char timeBuffer[80];
std::size_t charCount { std::strftime( timeBuffer, 80,
"%b %d %T",
&currentLocalTime)
};
if (charCount == 0) return -1;
std::cout << timeBuffer << "." << std::setfill('0') << std::setw(3) << now2.count() % 1000 << std::endl;
return 0;
}
If you are to format a system_clock::time_point in the format of numpy datetime64, you could use:
std::string format_time_point(system_clock::time_point point)
{
static_assert(system_clock::time_point::period::den == 1000000000 && system_clock::time_point::period::num == 1);
std::string out(29, '0');
char* buf = &out[0];
std::time_t now_c = system_clock::to_time_t(point);
std::strftime(buf, 21, "%Y-%m-%dT%H:%M:%S.", std::localtime(&now_c));
sprintf(buf+20, "%09ld", point.time_since_epoch().count() % 1000000000);
return out;
}
sample output: 2019-11-19T17:59:58.425802666

String representation of time_t?

time_t seconds;
time(&seconds);
cout << seconds << endl;
This gives me a timestamp. How can I get that epoch date into a string?
std::string s = seconds;
does not work
Try std::stringstream.
#include <string>
#include <sstream>
std::stringstream ss;
ss << seconds;
std::string ts = ss.str();
A nice wrapper around the above technique is Boost's lexical_cast:
#include <boost/lexical_cast.hpp>
#include <string>
std::string ts = boost::lexical_cast<std::string>(seconds);
And for questions like this, I'm fond of linking The String Formatters of Manor Farm by Herb Sutter.
UPDATE:
With C++11, use to_string().
Try this if you want to have the time in a readable string:
#include <ctime>
std::time_t now = std::time(NULL);
std::tm * ptm = std::localtime(&now);
char buffer[32];
// Format: Mo, 15.06.2009 20:20:00
std::strftime(buffer, 32, "%a, %d.%m.%Y %H:%M:%S", ptm);
For further reference of strftime() check out cppreference.com
The top answer here does not work for me.
See the following examples demonstrating both the stringstream and lexical_cast answers as suggested:
#include <iostream>
#include <sstream>
int main(int argc, char** argv){
const char *time_details = "2017-01-27 06:35:12";
struct tm tm;
strptime(time_details, "%Y-%m-%d %H:%M:%S", &tm);
time_t t = mktime(&tm);
std::stringstream stream;
stream << t;
std::cout << t << "/" << stream.str() << std::endl;
}
Output: 1485498912/1485498912
Found here
#include <boost/lexical_cast.hpp>
#include <string>
int main(){
const char *time_details = "2017-01-27 06:35:12";
struct tm tm;
strptime(time_details, "%Y-%m-%d %H:%M:%S", &tm);
time_t t = mktime(&tm);
std::string ts = boost::lexical_cast<std::string>(t);
std::cout << t << "/" << ts << std::endl;
return 0;
}
Output: 1485498912/1485498912
Found: here
The 2nd highest rated solution works locally:
#include <iostream>
#include <string>
#include <ctime>
int main(){
const char *time_details = "2017-01-27 06:35:12";
struct tm tm;
strptime(time_details, "%Y-%m-%d %H:%M:%S", &tm);
time_t t = mktime(&tm);
std::tm * ptm = std::localtime(&t);
char buffer[32];
std::strftime(buffer, 32, "%Y-%m-%d %H:%M:%S", ptm);
std::cout << t << "/" << buffer;
}
Output: 1485498912/2017-01-27 06:35:12
Found: here
Standard C++ does not have any time/date functions of its own - you need to use the C localtime and related functions.
the function "ctime()" will convert a time to a string.
If you want to control the way its printed, use "strftime". However, strftime() takes an argument of "struct tm". Use "localtime()" to convert the time_t 32 bit integer to a struct tm.
The C++ way is to use stringstream.
The C way is to use snprintf() to format the number:
char buf[16];
snprintf(buf, 16, "%lu", time(NULL));
Here's my formatter -- comments welcome. This q seemed like it had the most help getting me to my a so posting for anyone else who may be looking for the same.
#include <iostream>
#include "Parser.h"
#include <string>
#include <memory>
#include <ctime>
#include <chrono>
#include <iomanip>
#include <thread>
using namespace std;
string to_yyyyMMddHHmmssffffff();
string to_yyyyMMddHHmmssffffff() {
using namespace std::chrono;
high_resolution_clock::time_point pointInTime = high_resolution_clock::now();
std::time_t now_c = std::chrono::system_clock::to_time_t(pointInTime);
microseconds micros = duration_cast<microseconds>(pointInTime.time_since_epoch());
std::size_t fractional_microseconds = micros.count() % 1'000'000;
std:stringstream microstream;
microstream << "00000" << fractional_microseconds;
string formatted = microstream.str();
int index = formatted.length() - 6;
formatted = formatted.substr(index);
std::stringstream dateStream;
dateStream << std::put_time(std::localtime(&now_c), "%F %T") << "." << formatted;
formatted = dateStream.str();
return formatted;
}
There are a myriad of ways in which you might want to format time (depending on the time zone, how you want to display it, etc.), so you can't simply implicitly convert a time_t to a string.
The C way is to use ctime or to use strftime plus either localtime or gmtime.
If you want a more C++-like way of performing the conversion, you can investigate the Boost.DateTime library.
localtime did not work for me. I used localtime_s:
struct tm buf;
char dateString[26];
time_t time = time(nullptr);
localtime_s(&buf, &time);
asctime_s(dateString, 26, &buf);