Timestamp conversion using cplusplus [duplicate] - c++

How do I get a uint unix timestamp in C++? I've googled a bit and it seems that most methods are looking for more convoluted ways to represent time. Can't I just get it as a uint?

C++20 introduced a guarantee that time_since_epoch is relative to the UNIX epoch, and cppreference.com gives an example that I've distilled to the relevant code, and changed to units of seconds rather than hours:
#include <iostream>
#include <chrono>
int main()
{
const auto p1 = std::chrono::system_clock::now();
std::cout << "seconds since epoch: "
<< std::chrono::duration_cast<std::chrono::seconds>(
p1.time_since_epoch()).count() << '\n';
}
Using C++17 or earlier, time() is the simplest function - seconds since Epoch, which for Linux and UNIX at least would be the UNIX epoch. Linux manpage here.
The cppreference page linked above gives this example:
#include <ctime>
#include <iostream>
int main()
{
std::time_t result = std::time(nullptr);
std::cout << std::asctime(std::localtime(&result))
<< result << " seconds since the Epoch\n";
}

#include<iostream>
#include<ctime>
int main()
{
std::time_t t = std::time(0); // t is an integer type
std::cout << t << " seconds since 01-Jan-1970\n";
return 0;
}

The most common advice is wrong, you can't just rely on time(). That's used for relative timing: ISO C++ doesn't specify that 1970-01-01T00:00Z is time_t(0)
What's worse is that you can't easily figure it out, either. Sure, you can find the calendar date of time_t(0) with gmtime, but what are you going to do if that's 2000-01-01T00:00Z ? How many seconds were there between 1970-01-01T00:00Z and 2000-01-01T00:00Z? It's certainly no multiple of 60, due to leap seconds.

As this is the first result on google and there's no C++20 answer yet, here's how to use std::chrono to do this:
#include <chrono>
//...
using namespace std::chrono;
int64_t timestamp = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
In versions of C++ before 20, system_clock's epoch being Unix epoch is a de-facto convention, but it's not standardized. If you're not on C++20, use at your own risk.

#include <iostream>
#include <sys/time.h>
using namespace std;
int main ()
{
unsigned long int sec= time(NULL);
cout<<sec<<endl;
}

I created a global define with more information:
#include <iostream>
#include <ctime>
#include <iomanip>
#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) // only show filename and not it's path (less clutter)
#define INFO std::cout << std::put_time(std::localtime(&time_now), "%y-%m-%d %OH:%OM:%OS") << " [INFO] " << __FILENAME__ << "(" << __FUNCTION__ << ":" << __LINE__ << ") >> "
#define ERROR std::cout << std::put_time(std::localtime(&time_now), "%y-%m-%d %OH:%OM:%OS") << " [ERROR] " << __FILENAME__ << "(" << __FUNCTION__ << ":" << __LINE__ << ") >> "
static std::time_t time_now = std::time(nullptr);
Use it like this:
INFO << "Hello world" << std::endl;
ERROR << "Goodbye world" << std::endl;
Sample output:
16-06-23 21:33:19 [INFO] main.cpp(main:6) >> Hello world
16-06-23 21:33:19 [ERROR] main.cpp(main:7) >> Goodbye world
Put these lines in your header file. I find this very useful for debugging, etc.

Windows uses a different epoch and time units: see
Convert Windows Filetime to second in Unix/Linux
What std::time() returns on Windows is (as yet) unknown to me (;-))

Related

MM:hh:mm time with c ++

So I haven't seen here or anywhere else a way to get only the month hours and minutes using <ctime> or other library.
What I can do now is just get the full current date:
time_t now = time(0);
cout<<ctime(&now);
Any suggestions?
You can use the <ctime> standard library like this:
#include <ctime>
#include <iostream>
int main()
{
// get current time
std::time_t timer = std::time(0);
// convert to 'broken time'
std::tm bt = *std::localtime(&timer); // not thread safe
// extract month number from 'broken time' struct
std::cout << "month: " << (bt.tm_mon + 1) << '\n';
std::cout << "hours: " << (bt.tm_hour) << '\n';
std::cout << "mins : " << (bt.tm_min) << '\n';
}
The function std::localtime returns a pointer to an internal statc structure of type std::tm.
Because it returns a pointer to an internal struct it is best to copy it to a local version by dereferencing the pointer using *:
// copy what the returned pointer points to into `bt`.
std::tm bt = *std::localtime(&timer);
Since you are using ctime (C time), all C things should work. You could use strftime
char timestr[32];
strftime(timestr, sizeof(timestr), "%m:%H:%M", localtime(&now));
If boost is fine for you try this one :
boost::posix_time::to_simple_string(boost::posix_time::microsec_clock::local_time()).c_str()
try
std::put_time("%a %b %d %H:%M:%S %Y", &now);

Time stamp for saving file or folder?

Is there a simpler way to do a time stamp for saving a file/creating a directory as a date time stamp ?
only using standard library (not boost). Is there a faster way to do it ?
This is my current code
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::time_t tt = std::chrono::system_clock::to_time_t(now);
tm utc_tm = *gmtime(&tt);
oname.str("");
oname << (utc_tm.tm_year + 1900) << '-' << std::setfill('0') << std::setw(2) << (utc_tm.tm_mon + 1) << '-' << std::setfill('0') << std::setw(2) << utc_tm.tm_mday << " " << std::setfill('0') << std::setw(2)<< utc_tm.tm_hour <<':' << std::setfill('0') << std::setw(2) << utc_tm.tm_min <<':' << std::setfill('0') << std::setw(2) << utc_tm.tm_sec;
ts = oname.str();
There is a less tortuous way:
#include <string>
#include <ctime>
std::string get_timestamp()
{
auto now = std::time(nullptr);
char buf[sizeof("YYYY-MM-DD HH:MM:SS")];
return std::string(buf,buf +
std::strftime(buf,sizeof(buf),"%F %T",std::gmtime(&now)));
}
It is very probably also faster, because it is less tortuous, but that is
also very probably immaterial in a setting where disc I/O is in play.
This gives you the same timestamps as your own code, e.g.
2015-03-28 10:48:45
See std::time and
std::strftime to
understand how the desired formatting is achieved and note that std::strftime
returns the length of the string it has composed, excluding its nul-terminator.
This code is standard, but if you are working with MS VC++ 2013 or later then
you could also consider the use of std::put_time,
as in:
#include <iomanip>
#include <sstream>
#include <string>
#include <ctime>
std::string get_timestamp()
{
auto now = std::time(nullptr);
std::ostringstream os;
os << std::put_time(std::gmtime(&now),"%F %T");
return os.str();
}
which is simpler still. (I have not tested that.) std::put_time however
is unsupported by gcc as of 4.9.
Seemingly you want your timestamps formatted as YYYY-MM-DD HH:MM:SS. If they
are to be used in filenames, it would be more prudent to keep them free of spaces:
perhaps YYYY-MM-DD_HH:MM:SS.

Most simple way to get string containing time interval

I'm new to std::chrono and I'm looking for a simple way to construct a string containing a time interval formatted hhh:mm:ss (yes, 3 hour figures), indicating the difference between a start time point and now.
How would I go about this using a steady_clock? The examples on Cppreference don't quite fit this problem.
Any time you find yourself manually applying conversion factors among units with the <chrono> library, you should be asking yourself:
Why am I converting units manually? Isn't this what <chrono> is
supposed to do for me?!
A "conversion factor" is 60, or 1000, or 100, or whatever. If you see it in your code, you're opening yourself up to conversion factor errors.
Here is sasha.sochka's code rewritten without these conversion factors. And just to throw in how general this technique is, milliseconds are added for flare:
#include <chrono>
#include <string>
#include <sstream>
#include <iomanip>
#include <iostream>
int main() {
using namespace std::chrono;
steady_clock::time_point start;
steady_clock::time_point now = steady_clock::now();
auto d = now -start;
auto hhh = duration_cast<hours>(d);
d -= hhh;
auto mm = duration_cast<minutes>(d);
d -= mm;
auto ss = duration_cast<seconds>(d);
d -= ss;
auto ms = duration_cast<milliseconds>(d);
std::ostringstream stream;
stream << std::setfill('0') << std::setw(3) << hhh.count() << ':' <<
std::setfill('0') << std::setw(2) << mm.count() << ':' <<
std::setfill('0') << std::setw(2) << ss.count() << '.' <<
std::setfill('0') << std::setw(3) << ms.count();
std::string result = stream.str();
std::cout << result << '\n';
}
There are other ways to do this without exposed conversion factors, this way is only an example. My main point is: avoid hardcoding unit conversion factors in your code. They are error prone. Even if you get it right when you first code it, conversion factors are vulnerable to future code maintenance. You can future-proof your code by demanding that all unit conversions happen within the <chrono> library.
As Joachim Pileborg noted higher in the comments there is no function for format a string from a duration object. But you can do it using duration_cast to convert time difference first to hours and then minutes and seconds.
After that using C++11 to_string function you can concatenate them to get the resulting string.
#include <chrono>
#include <string>
#include <sstream>
#include <iomanip>
int main() {
using namespace std::chrono;
steady_clock::time_point start = /* Some point in time */;
steady_clock::time_point now = steady_clock::now();
int hhh = duration_cast<hours>(now - start).count();
int mm = duration_cast<minutes>(now - start).count() % 60;
int ss = duration_cast<seconds>(now - start).count() % 60;
std::ostringstream stream;
stream << std::setfill('0') << std::setw(3) << hhh << ':' <<
std::setfill('0') << std::setw(2) << mm << ':' <<
std::setfill('0') << std::setw(2) << ss;
std::string result = stream.str();
}

can boost gregorian date and boost posix time properly calculate unixtime?

I am trying to write a simple timestamping system that provides epoch seconds and fractional seconds from the current time. I am using boost library and have something like this:
const boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1));
boost::posix_time::ptime time() {
boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
return now;
}
boost::posix_time::time_duration dur = (time() - epoch);
and then use the following elements to extract the epoch values:
dur.total_seconds();
dur.fractional_seconds();
Specifically, will this return a proper unix time? If not, any suggestions as to how to correct it? Thanks.
Yes, that should work, but, to be certain, there's always experimental evidence:
#include <iostream>
#include <time.h>
#include <boost/date_time.hpp>
namespace bpt = boost::posix_time;
namespace bg = boost::gregorian;
int main()
{
bpt::time_duration dur = bpt::microsec_clock::universal_time()
- bpt::ptime(bg::date(1970, 1, 1));
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
std::cout << std::setfill('0')
<< " boost: " << dur.total_seconds() << '.' << std::setw(6)
<< dur.fractional_seconds() << '\n'
<< " ctime: " << time(NULL) << '\n'
<< " posix: " << ts.tv_sec << '.' << std::setw(9)
<< ts.tv_nsec << '\n';
}
I get
Linux/gcc
boost: 1361502964.664746
ctime: 1361502964
posix: 1361502964.664818326
Sun/Sun Studio
boost: 1361503762.775609
ctime: 1361503762
posix: 1361503762.775661600
AIX/XLC
boost: 1361503891.342930
ctime: 1361503891
posix: 1361503891.342946000
and even Windows/Visual Studio
boost: 1361504377.084231
ctime: 1361504377
Looks like they all agree on how many seconds passed since date(1970,1,1)

Capturing a time in milliseconds

The following piece of code is used to print the time in the logs:
#define PRINTTIME() struct tm * tmptime;
time_t tmpGetTime;
time(&tmpGetTime);
tmptime = localtime(&tmpGetTime);
cout << tmptime->tm_mday << "/" <<tmptime->tm_mon+1 << "/" << 1900+tmptime->tm_year << " " << tmptime->tm_hour << ":" << tmptime->tm_min << ":" << tmptime->tm_sec<<">>";
Is there any way to add milliseconds to this?
To have millisecond precision you have to use system calls specific to your OS.
In Linux you can use
#include <sys/time.h>
timeval tv;
gettimeofday(&tv, 0);
// then convert struct tv to your needed ms precision
timeval has microsecond precision.
In Windows you can use:
#include <Windows.h>
SYSTEMTIME st;
GetSystemTime(&st);
// then convert st to your precision needs
Of course you can use Boost to do that for you :)
//C++11 Style:
cout << "Time in Milliseconds =" <<
chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now().time_since_epoch()).count()
<< std::endl;
cout << "Time in MicroSeconds=" <<
chrono::duration_cast<chrono::microseconds>(chrono::steady_clock::now().time_since_epoch()).count()
<< std::endl;
You need a timer with a higher resolution in order to capture milliseconds. Try this:
int cloc = clock();
//do something that takes a few milliseconds
cout << (clock() - cloc) << endl;
This is of course dependent on your OS.
The high resolution timers are usually gettimeofday on Linux style platforms and QueryPerformanceCounter on Windows.
You should be aware that timing the duration of a single operation (even with a high resolution timer) will not yield accurate results. There are too many random factors at play. To get reliable timing information, you should run the task to be timed in a loop and compute the average task time. For this type of timing, the clock() function should be sufficient.
If you don't want to use any OS-specific code, you can use the ACE package which supplies the ACE_OS::gettimeofday function for most standard operating systems.
For example:
ACE_Time_Value startTime = ACE_OS::gettimeofday();
do_something();
ACE_Time_Value endTime = ACE_OS::gettimeofday();
cout << "Elapsed time: " << (endTime.sec() - startTime.sec()) << " seconds and " << double(endTime.usec() - startTime.usec()) / 1000 << " milliseconds." << endl;
This code will work regardless of your OS (as long as ACE supports this OS).
In Ubuntu 16.04 this worked for me...
const std::string currentDateTime() {
char fmt[64], buf[64];
struct timeval tv;
struct tm *tm;
gettimeofday(&tv, NULL);
tm = localtime(&tv.tv_sec);
strftime(fmt, sizeof fmt, "%Y-%m-%d %H:%M:%S.%%06u", tm);
snprintf(buf, sizeof buf, fmt, tv.tv_usec);
return buf;
}
Then, with...
std::cout << currentDateTime();
I get...
2016-12-29 11:09:55.331008
New answer for old question using C++11 or C++14 and this free, open-source library:
#include "tz.h"
#include <iostream>
int
main()
{
using namespace date;
using namespace std;
using namespace std::chrono;
auto now = make_zoned(current_zone(), floor<milliseconds>(system_clock::now()));
cout << format("%e/%m/%Y %T", now) << '\n';
}
This just output for me:
16/01/2017 15:34:32.167
which is my current local date and time to millisecond precision. By eliminating the floor<milliseconds>() you will automatically get whatever precision your system_clock has.
If you wanted the result as a UTC timestamp instead of a local timestamp, it is even easier:
auto now = floor<milliseconds>(system_clock::now());
cout << format("%e/%m/%Y %T", now) << '\n';
And if you want a UTC timestamp and you aren't picky about the precision or the format, you can just:
cout << system_clock::now() << '\n';
which just output for me:
2017-01-16 20:42:11.267245