Local time with milliseconds - c++

how can I get current time with library boost. I can do this:
ptime now = boost::posix_timesecond_clock::local_time();
tm d_tm = to_tm(now);
But the last time unit of tm structure is second and I need in millisecond. Can I get current time with milliseconds?

look at boost::posix_time::microsec_clock::local_time()
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <iostream>
int
main()
{
boost::posix_time::ptime time = boost::posix_time::microsec_clock::local_time();
boost::posix_time::time_duration duration( time.time_of_day() );
std::cout << duration.total_milliseconds() << std::endl;
return 0;
}

I think the code should be:
ptime now = boost::posix_time::second_clock::local_time();
I think you forget the "::" in the codes. ^_^

Related

C++ timedelta with strftime?

I want to do a function to get the current time with a certain format. C++ is not my main language but im trying to do this:
current_datetime(timezone='-03:00', offset=timedelta(seconds=120))
def current_datetime(fmt='%Y-%m-%dT%H:%M:%S', timezone='Z', offset=None):
offset = offset or timedelta(0)
return (datetime.today() + offset).strftime(fmt) + timezone
My best so far searching internet was this, but is missing the offset part:
#include <iostream>
#include <ctime>
std::string current_datetime(std::string timezone="Z", int offset=1)
{
std::time_t t = std::time(nullptr);
char mbstr[50];
std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%dT%H:%M:%S", std::localtime(&t));
std::string formated_date(mbstr);
formated_date += std::string(timezone);
return formated_date;
}
int main()
{
std::cout << current_datetime() << std::endl; //2021-10-26T21:34:48Z
std::cout << current_datetime("-05:00") << std::endl; //2021-10-26T21:34:48-05:00
return 0;
}
The idea is to get a string that is a "start date" and one as "end date" that is X seconds in the future. Im stuck with the offset/delta part
Just add the offset to the seconds since epoch.
std::time_t t = std::time(nullptr) + offset;
You would also make offset of type std::time_t, as it represents a distance in time in seconds.

How to measure elapsed time without being affected by changes in system time

I want to measure elapsed time in seconds. With std::chrono::steady_clock I do it. However it suffers from system time changes.
Wasn't steady_clock supposed to not being affected by changes in system time?
How can I do that?
Here is the code:
#include <iostream>
#include <chrono>
#include <time.h>
std::chrono::steady_clock::time_point t = std::chrono::steady_clock::now();
/* Change system time */
std::time_t tnow = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
tnow -= 20;
std::cout << "stime: " << stime(&tnow) << std::endl;
/********************************************************/
sleep(5);
std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
std::cout << "ELAPSED: " << std::chrono::duration_cast<std::chrono::seconds>(t2-t).count() << std::endl;
This results:
stime: 0
ELAPSED: -15
What I wanted to get was:
ELAPSED: 5
Edit:
I have added C tag, because it seems that it is a kernel (or buildroot of board) bug. So, how could I achieve this without chrono? I mean, in a straight way (without having to watch system time changes).
How was the people living before chrono?
You can file a bug with your vendor.
From the standard:
Objects of class steady_­clock represent clocks for which values of
time_­point never decrease as physical time advances and for which
values of time_­point advance at a steady rate relative to real
time. That is, the clock may not be adjusted.
If you can find a reliable source of monotonic time on your system, you can easily wrap that source in a custom chrono::clock and subsequently still make use of the type-safe chrono system. For example:
#include <chrono>
struct MyClock
{
using duration = std::chrono::nanoseconds;
using rep = duration::rep;
using period = duration::period;
using time_point = std::chrono::time_point<MyClock>;
static constexpr bool is_steady = true;
static time_point now() noexcept
{
using namespace std::chrono;
timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return time_point{seconds{ts.tv_sec} + nanoseconds{ts.tv_nsec}};
}
};
Now you can say things like:
MyClock::time_point t = MyClock::now();
// ...
MyClock::time_point t2 = MyClock::now();
std::cout << "ELAPSED: " << std::chrono::duration_cast<std::chrono::seconds>(t2-t).count() << std::endl;

Epoch time to date/time format in boost c++

In Linux, i am reading epoch time from "/proc/stat" as btime and i want to convert to readable date and time format with c++ boost.
I have tried below things and date is working properly.
time_t btime_ = 1505790902; //This is epoch time read from "/proc/stat" file.
std::wstring currentDate_ = L"";
boost::gregorian::date current_date_ =
boost::posix_time::from_time_t(btime_).date();
std::wstring year_ = boost::lexical_cast<std::wstring>
(current_date_.year());
std::wstring day_ = boost::lexical_cast<std::wstring>
(current_date_.day());
Here i am getting correct year and day. BUT How can i get time( HH::MM:SS) from above epoch time ? Let me give hint - i can try.
Thanks in Advance.
Just:
Live On Coliru
#include <ctime>
#include <boost/date_time/posix_time/posix_time_io.hpp>
int main() {
std::time_t btime_ = 1505790902; //This is epoch time read from "/proc/stat" file.
std::cout << boost::posix_time::from_time_t(btime_) << "\n";
std::cout.imbue(std::locale(std::cout.getloc(), new boost::posix_time::time_facet("%H:%M:%S")));
std::cout << boost::posix_time::from_time_t(btime_) << "\n";
}
Prints
2017-Sep-19 03:15:02
03:15:02
UPDATE
To the comment:
Live On Coliru
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/date_time/c_local_time_adjustor.hpp>
namespace pt = boost::posix_time;
namespace g = boost::gregorian;
using local_adj = boost::date_time::c_local_adjustor<pt::ptime>;
int main() {
std::cout.imbue(std::locale(std::cout.getloc(), new pt::time_facet("%H:%M:%S")));
std::time_t btime_ = 1505790902; // This is epoch time read from "/proc/stat" file.
pt::ptime const timestamp = pt::from_time_t(btime_);
std::cout << timestamp << "\n";
// This local adjustor depends on the machine TZ settings
std::cout << local_adj::utc_to_local(timestamp) << " local time\n";
}
Prints
+ TZ=CEST
+ ./a.out
03:15:02
03:15:02 local time
+ TZ=MST
+ ./a.out
03:15:02
20:15:02 local time
You can use a time_facet. Here's an example that prints UTC date/time:
std::string PrintDateTime()
{
std::stringstream str;
boost::posix_time::time_facet *facet = new boost::posix_time::time_facet("%d.%m.%Y-%H:%M:%S-UTC");
str.imbue(std::locale(str.getloc(), facet));
str << boost::posix_time::second_clock::universal_time(); //your time point goes here
return str.str();
}
Notice that you don't need to worry about the memory management of facet. It's taken care of already from within boost.

How to get date and time string accurate to milliseconds in C++ in Linux?

I want to be able to put into a string the local time and date with millisecond resolution like so:
YYYY-MM-DD hh:mm:ss.sss
Seems like a simple thing to do, but I haven't found a simple answer for how to do this. I am writing in C++ and do have access to 11 compiler but am fine using a C solution if it's cleaner. I found a post here with a solution Get both date and time in milliseconds but surely it can't be that difficult given use of standard libraries. I'm probably going to move forward with that type of solution but was hoping to add to the knowledge base by asking the question here on SO.
I know this will work but again, seems unnecessarily difficult:
#include <sys/time.h>
#include <stdio.h>
int main(void)
{
string sTimestamp;
char acTimestamp[256];
struct timeval tv;
struct tm *tm;
gettimeofday(&tv, NULL);
tm = localtime(&tv.tv_sec);
sprintf(acTimestamp, "%04d-%02d-%02d %02d:%02d:%02d.%03d\n",
tm->tm_year + 1900,
tm->tm_mon + 1,
tm->tm_mday,
tm->tm_hour,
tm->tm_min,
tm->tm_sec,
(int) (tv.tv_usec / 1000)
);
sTimestamp = acTimestamp;
cout << sTimestamp << endl;
return 0;
}
Tried looking at put_time for C++ and strftime for the old C way. Both only allow me to get to second resolution best I can tell. You can see the two approaches I've gotten so far below. I would like to put it into a string
auto t = std::time(nullptr);
auto tm = *std::localtime(&t);
std::cout << std::put_time(&tm, "%Y-%m-%d %H:%M:%S") << std::endl;
time_t rawtime;
struct tm * timeinfo;
char buffer[80];
time (&rawtime);
timeinfo = localtime(&rawtime);
strftime(buffer,sizeof(buffer),"%Y-%m-%d %I:%M:%S",timeinfo);
std::string str(buffer);
std::cout << str;
Only thing I can figure out is to use gettimeofday and get rid of all the data except the last second and append it to the timestamp, still wish there was a cleaner approach.
Anyone find a solution that works better?
I would recommend looking at Howard Hinnant's date library. One of the examples given in the wiki shows how to get the current local time, up to the given precision of your std::chrono::system_clock implementation (nanoseconds on Linux, from memory?):
EDIT: As Howard points out in the comments, you can use date::floor() to obtain the desired precision. So to generate a string as requested in the question, you could do something like this:
#include "tz.h"
#include <iostream>
#include <string>
#include <sstream>
std::string current_time()
{
const auto now_ms = date::floor<std::chrono::milliseconds>(std::chrono::system_clock::now());
std::stringstream ss;
ss << date::make_zoned(date::current_zone(), now_ms);
return ss.str();
}
int main()
{
std::cout << current_time() << '\n';
}

Get current time in milliseconds using C++ and Boost

In my thread (using boost::thread) I need to retrieve the current time in ms or less and to convert into ms:
Actually, reading here I've found this:
tick = boost::posix_time::second_clock::local_time();
now = boost::posix_time::second_clock::local_time();
And seems to work, but after I need to have a long value of the milliseconds of the now...
How can I do it?
You can use boost::posix_time::time_duration to get the time range. E.g like this
boost::posix_time::time_duration diff = tick - now;
diff.total_milliseconds();
And to get a higher resolution you can change the clock you are using. For example to the boost::posix_time::microsec_clock, though this can be OS dependent. On Windows, for example, boost::posix_time::microsecond_clock has milisecond resolution, not microsecond.
An example which is a little dependent on the hardware.
int main(int argc, char* argv[])
{
boost::posix_time::ptime t1 = boost::posix_time::second_clock::local_time();
boost::this_thread::sleep(boost::posix_time::millisec(500));
boost::posix_time::ptime t2 = boost::posix_time::second_clock::local_time();
boost::posix_time::time_duration diff = t2 - t1;
std::cout << diff.total_milliseconds() << std::endl;
boost::posix_time::ptime mst1 = boost::posix_time::microsec_clock::local_time();
boost::this_thread::sleep(boost::posix_time::millisec(500));
boost::posix_time::ptime mst2 = boost::posix_time::microsec_clock::local_time();
boost::posix_time::time_duration msdiff = mst2 - mst1;
std::cout << msdiff.total_milliseconds() << std::endl;
return 0;
}
On my win7 machine. The first out is either 0 or 1000. Second resolution.
The second one is nearly always 500, because of the higher resolution of the clock. I hope that help a little.
If you mean milliseconds since epoch you could do
ptime time_t_epoch(date(1970,1,1));
ptime now = microsec_clock::local_time();
time_duration diff = now - time_t_epoch;
x = diff.total_milliseconds();
However, it's not particularly clear what you're after.
Have a look at the example in the documentation for DateTime at Boost Date Time
// Get current date/time in milliseconds.
#include "boost/date_time/posix_time/posix_time.hpp"
namespace pt = boost::posix_time;
int main()
{
pt::ptime current_date_microseconds = pt::microsec_clock::local_time();
long milliseconds = current_date_microseconds.time_of_day().total_milliseconds();
pt::time_duration current_time_milliseconds = pt::milliseconds(milliseconds);
pt::ptime current_date_milliseconds(current_date_microseconds.date(),
current_time_milliseconds);
std::cout << "Microseconds: " << current_date_microseconds
<< " Milliseconds: " << current_date_milliseconds << std::endl;
// Microseconds: 2013-Jul-12 13:37:51.699548 Milliseconds: 2013-Jul-12 13:37:51.699000
}
Try this: import headers as mentioned.. gives seconds and milliseconds only. If you need to explain the code read this link.
#include <windows.h>
#include <stdio.h>
void main()
{
SYSTEMTIME st;
SYSTEMTIME lt;
GetSystemTime(&st);
// GetLocalTime(&lt);
printf("The system time is: %02d:%03d\n", st.wSecond, st.wMilliseconds);
// printf("The local time is: %02d:%03d\n", lt.wSecond, lt.wMilliseconds);
}