C++ - Calculate the millisecond from ptime in total seconds - c++

How do i calculate the millisecond difference from the following Ptime ,I am using boost::ptime
I'm trying to calculate the time_duration in milliseconds to find the difference. i get value like 999975 but expected value is 975
ptime PreviousgpsTime = Mon Jun 28 17:07:10.054 2021
ptime NextgpsTime = Mon Jun 28 17:07:11.025 2021
double totalDiff = (NextgpsTime-PreviousgpsTime).total_milliseconds();
How to fix this and get the actual time duration.

Live On Coliru:
#include <boost/date_time/posix_time/posix_time.hpp>
int main()
{
using namespace boost::posix_time;
ptime PreviousgpsTime = time_from_string("2021-Jun-28 17:07:10.054");
ptime NextgpsTime = time_from_string("2021-Jun-28 17:07:11.025");
long totalDiff = (NextgpsTime - PreviousgpsTime).total_milliseconds();
std::cout << "From " << PreviousgpsTime << " to " << NextgpsTime << " is " << totalDiff << "ms\n";
}
Prints
From 2021-Jun-28 17:07:10.054000 to 2021-Jun-28 17:07:11.025000 is 971ms

Related

How to deal with timezone and Windows FILETIME in C++?

I have a windows filetime (for example, 132522078890080000)
In Python I easily can convert it like that. Result is 1607716289 (Sat Dec 12 2020 00:51:29 GMT+0500 (Yekaterinburg Standard Time)). That's right!
But in C++ I tried to convert it like that
#include <iostream>
#include <ctime>
#define WINDOWS_TICK 10000000
#define SEC_TO_UNIX_EPOCH 11644473600LL
uint64_t WindowsTickToUnixSeconds(uint64_t windowsTicks)
{
return (uint64_t)(windowsTicks / WINDOWS_TICK - SEC_TO_UNIX_EPOCH);
}
int main() {
const uint64_t in_raw = 132522078890080000;
auto unix_timestamp = WindowsTickToUnixSeconds(in_raw);
time_t out = unix_timestamp;
std::cout << "Timestamp: " << unix_timestamp << std::endl;
std::cout << "Local: " << asctime(localtime(&out)) << std::endl;
std::cout << "GMT: " << asctime(gmtime(&out)) << std::endl;
return 0;
}
And result of that is
Timestamp: 1607734289
Local: Sat Dec 12 05:51:29 2020
GMT: Sat Dec 12 00:51:29 2020
As you can see the timestamps are different (1607734289, 1607716289, difference is 5 hours (because timezone is Asia/Yekaterinburg)).
I can easily subtract 5 hours but in that case it won't work in another timezone.
So how can I get correct timestamp?

Get year/month/day h/m/s/ns from Boost local_date_time object?

I have converted a timestamp (UTC) since Epoch to a boost::posix_time::ptime and applied a timezone, resulting in a boost::local_time::local_date_time object. However, I cannot retrieve the year, month, day, hh/mm/ss/ns or nanoseconds since midnight for the adjusted date time.
It appears the local_date_time object doesn't provide getters for these.
I can't get these from the boost::posix_time::ptime because it hasn't been shifted for timezone.
What's the best approach?
using namespace boost::gregorian;
using namespace boost::local_time;
using namespace boost::posix_time;
// Create timezone
tz_database tz_db;
tz_db.load_from_file("libs/date_time/data/date_time_zonespec.csv");
time_zone_ptr chicago_tz = tz_db.time_zone_from_region("America/Chicago");
// Create Epoch offset (seconds)
std::time_t btime_ = nanosSinceEpochUTC / 1E9;
ptime dateTime = boost::posix_time::from_time_t(btime_);
// Create local Chicago time at Epoch offset
const local_date_time chicago(dateTime, chicago_tz);
// I need to retrieve the year/month/day/hh/mm/ss etc from the adjusted time, not the ptime.
The time properties are in the time_of_day() sub object. The representation type of that subobject is time_duration and it has all the accessors you want:
Live On Coliru
#include <boost/date_time/local_time/local_time.hpp>
#include <boost/date_time/tz_db_base.hpp>
int main() {
// Create timezone
boost::local_time::tz_database tz_db;
{
std::istringstream iss(R"("America/Chicago","CST","Central Standard Time","CDT","Central Daylight Time","-06:00:00","+01:00:00","2;0;3","+02:00:00","1;0;11","+02:00:00")");
tz_db.load_from_stream(iss);
}
auto chicago_tz = tz_db.time_zone_from_region("America/Chicago");
// Create Epoch offset (seconds)
std::time_t btime_ = 1596241091; // nanosSinceEpochUTC / 1E9;
auto dateTime = boost::posix_time::from_time_t(btime_);
std::cout << "ptime: " << dateTime << "\n";
// Create local Chicago time at Epoch offset
const boost::local_time::local_date_time chicago(dateTime, chicago_tz);
std::cout << "local_date_time: " << chicago << "\n";
// I need to retrieve the year/month/day/hh/mm/ss etc from the adjusted
// time, not the ptime.
std::cout << "year/m/d: " << chicago.local_time().date() << "\n";
auto tod = chicago.local_time().time_of_day();
std::cout << "time_of_day: " << tod << "\n";
std::cout << "hh, mm, ss: " <<
tod.hours() << ", " <<
tod.minutes() << ", " <<
tod.seconds() << "\n";
}
As you can see, it's important to access through the local_time() accessor. Note how all the items (day, month, hours) wrapped back correctly according to the time zone.
Prints:
ptime: 2020-Aug-01 00:18:11
local_date_time: 2020-Jul-31 19:18:11 CDT
year/m/d: 2020-Jul-31
time_of_day: 19:18:11
hh, mm, ss: 19, 18, 11
What I do is as follows: I am naming one class after the name of a time zone. In my case gmt and fetch everything via instances of my very own time as well as date class.
class gmt {
string get(string& s) {
this->dt= this->d.getDay();
this->tm= this->d.getTime();
s= "expires="+this->d.getName(this->d.getDayName())
+", " +this->dt.substr( 0, 2) +"-" +this->d.getMonthName() +"-" +this->dt.substr( 8, 2)
+" " +this->tm +" GMT";
return s;
}
friend class cookie;
string dt, tm;
MyDate d;
};
Okay, it isn't "boost" but you can solve it via its own std and isn't that contrary.

Why isnt't this code with std::chrono::system_clock working?

I was trying to create a program who tells me what day is tomorrow (starting from 01 Jan) but the code I wrote down doesn't seem to work.
This is my code:
#include <iostream>
#include <ctime>
#include <ratio>
#include <chrono>
int main (int argc, char** argv) {
std::chrono::system_clock::time_point today = std::chrono::system_clock::now();
std::tm timeinfo = std::tm();
timeinfo.tm_mon = 0;
timeinfo.tm_mday = 1;
std::time_t tt = std::mktime (&timeinfo);
std::chrono::system_clock::time_point tp = std::chrono::system_clock::from_time_t (tt);
std::chrono::duration<int,std::ratio<60*60*24> >one_day (1);
std::chrono::system_clock::time_point tomorrow = today + one_day;
std::time_t tv;
tt = std::chrono::system_clock::to_time_t ( today );
std::cout << "today is: " << ctime(&tv);
tt = std::chrono::system_clock::to_time_t ( tomorrow );
std::cout << "tomorrow will be: " << ctime(&tv);
return 0;
}
I'm not getting any error when I compile my code, but when I run my program the output is:
today is: Thu Jan 01 01:00:34 1970
tomorrow will be: Thu Jan 01 01:00:34 1970
Why is it acting this way?
Thanks everybody!
Actually your program is correct. You just messed up the output. The variables used in ctime refer to the (non-initialized) variable tv instead of the variable tt that holds the values you compute from today and tomorrow.
tt = std::chrono::system_clock::to_time_t ( today );
std::cout << "today is: " << ctime(&tv);
tt = std::chrono::system_clock::to_time_t ( tomorrow );
std::cout << "tomorrow will be: " << ctime(&tv);
Should be
tt = std::chrono::system_clock::to_time_t ( today );
std::cout << "today is: " << ctime(&tt);
tt = std::chrono::system_clock::to_time_t ( tomorrow );
std::cout << "tomorrow will be: " << ctime(&tt);
instead. After correcting that, it works for me. I now get this output:
today is: Sun Jan 31 13:22:30 2016
tomorrow will be: Mon Feb 1 13:22:30 2016
Your variable tv is uninitialized!
See my comments annotating your source code:
std::time_t tv; // uninitialized
tt = std::chrono::system_clock::to_time_t(today);
std::cout << "today is: " << ctime(&tv); // did you mean tt?
tt = std::chrono::system_clock::to_time_t(tomorrow);
std::cout << "tomorrow will be: " << ctime(&tv); // did you mean tt?

Converting 13 decimals to datetime

I have a project about cars with GPS. I need to return the start and the finish moment for each car.
So we have:
time_t x, y;
Because I will use later them for a transformation.
I have a problem. I read from an external file data in this format:
auto1
1439467747492
auto1
1439467748512
...etc.
auto1->name of the car;
1439467747492->the moment in time of the car
I tried to get the first position of the first moment and the last moment for each car. This is the code in C++:
long test = momenti[choice1]/1000;
time_t x = test;
cout << " Momentul initial:\n " << ctime(&x) << endl;
long test1 = momentf[choice1] / 1000;
time_t y = test1;
cout << " Momentul final:\n " << ctime(&y) << endl;
I receive the same date for every car. Is something like momenti[i]=momentf[i]
What did I do wrong?
It is not good. According epoch converter we should get this : GMT: Thu, 13 Aug 2015 12:09:07 GMT
Here is how you can get this output with C++11/14 and using this free, open source date library which extends the C++ <chrono> library to handle dates.
#include "date.h"
#include <chrono>
#include <iostream>
int
main()
{
using namespace std::chrono;
using namespace std;
using namespace date;
using time_point = std::chrono::time_point<system_clock, milliseconds>;
auto tp = time_point{1439467747492ms};
auto dp = floor<days>(tp);
auto time = make_time(tp - dp);
auto ymd = year_month_day{dp};
cout << "GMT: " << weekday{dp} << ", " << ymd.day() << ' ' << ymd.month()
<< ' ' << ymd.year() << ' ' << time << " GMT\n";
}
Output:
GMT: Thu, 13 Aug 2015 12:09:07.492 GMT
I threw in the fractional seconds for fun, and it seemed a shame to waste them (the C lib won't give them to you). If you really don't want them, it is easy to fix:
auto time = make_time(floor<seconds>(tp) - dp);
Now the output is:
GMT: Thu, 13 Aug 2015 12:09:07 GMT
You need C++14 for the 1439467747492ms above. If you only have C++11 you can sub in this instead: milliseconds{1439467747492}. If you only have C++03, then you are 13 years behind the times and stuck with ctime. ;-)
The chrono solution will offer you greater type safety, more flexibility, and greater performance.
If i can fix and the latitude and longitude problem would be great lol
If you can translate latitude and longitude into an IANA timezone name (and there are tools to do this), I've got a IANA timezone database parser for you which interoperates with <chrono> and "date.h".
#include <iostream>
#include <cstring>
#include <time.h>
using namespace std;
int main()
{
long test = 1439467747492;
time_t x = test;
cout << ctime( &x ) << endl;
return 0;
}
Produces
Tue Sep 18 20:15:32 1990

Get time difference with DST considered

I am using Boost.Date_time to get the time difference between two dates. I want the code to consider DST change as well during these days and give me the correct interval.
Consider this example. On 1-Nov-2015, the DST is going to change in USA. At 2:00 hours, the clock will be moved back to 1:00. The output of the below code doesn't reflect that. It gives 23 hours as the difference.
date d1(2015, 11, 1);
ptime nov1_00(d1, hours(0));
ptime nov1_23(d1, hours(23));
seconds = (nov1_23 - nov1_00).total_seconds();
Output:
2015-Nov-01 00:00:00. 2015-Nov-01 23:00:00. Seconds: 82800
Is there a way in boost to specify the DST requirement in this scenario?
You should be using local times:
Live On Coliru
#include <boost/date_time/local_time/local_time.hpp>
#include <boost/date_time/local_time/local_date_time.hpp>
#include <boost/date_time/local_time/local_time_io.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
int main() {
namespace lt = boost::local_time;
namespace pt = boost::posix_time;
using date = boost::gregorian::date;
lt::tz_database db;
db.load_from_file("/home/sehe/custom/boost/libs/date_time/data/date_time_zonespec.csv");
//for (auto region : db.region_list()) std::cout << region << "\n";
auto NY = db.time_zone_from_region("America/New_York");
date const d1(2015, 11, 1);
lt::local_date_time nov1_00(d1, pt::hours(0), NY, true);
lt::local_date_time nov1_23(d1, pt::hours(23), NY, false);
lt::local_time_period period(nov1_00, nov1_23);
std::cout << "period: " << period << "\n";
std::cout << "duration: " << period.length() << "\n";
// if you insist:
auto seconds = (nov1_23 - nov1_00).total_seconds();
std::cout << "seconds: " << seconds << "\n";
}
Prints:
period: [2015-Nov-01 00:00:00 EDT/2015-Nov-01 22:59:59.999999 EST]
duration: 24:00:00
seconds: 86400