Convert UTCTime to Local Time - c++11

I have UTCTimeStamp Value {1507272767979279596} and I want to convert into human readable format.
for example
UTCTimestamp = 1507272767979279596
and
Human readable form is = Friday, October 6, 2017 12:22:47.979 PM
is there any function in C++ STL or Boost,
which can get me above output.

Fair warning: you look to have a weird timezone (+05:30?). Other than that:
Live On Coliru
#include <ctime>
#include <string>
std::string usingStrftime(const time_t rawtime)
{
struct tm * dt = localtime(&rawtime);
char buffer[30];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", dt);
return std::string(buffer);
}
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/conversion.hpp>
#include <boost/date_time/posix_time/ptime.hpp>
boost::posix_time::ptime as_ptime(uintmax_t ns) {
return {{1970,1,1}, boost::posix_time::microseconds(ns/1000)};
}
#include <iostream>
int main() {
std::cout << usingStrftime(1507272767) << "\n";
auto timestamp = as_ptime(1507272767979279596ull);
std::cout << timestamp << "\n";
std::cout.imbue(std::locale(std::cout.getloc(), new boost::posix_time::time_facet("%A %b %d, %Y %I:%M:%S %p")));
std::cout << timestamp << "\n";
}
Prints
2017-10-06 06:52:47
2017-Oct-06 06:52:47.979279
Friday Oct 06, 2017 06:52:47 AM

Related

How to convert boost::posix_time::ptime to YYMMDDHHMM?

I am trying to convert boost::posix_time::ptime to YYMMDDHHMM format string. How to accomplish this?
Related: How to convert a boost::ptime to string
#include <iostream>
#include <cstdlib>
#include <string>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/format.hpp>
int main()
{
std::string submitDateString = "20190911T235959";
boost::posix_time::ptime submitPtime = boost::posix_time::from_iso_string( submitDateString );
// Use a facet to display time in a custom format (only hour and minutes).
std::stringstream sstream;
boost::posix_time::time_facet* facet = new boost::posix_time::time_facet();
facet->format("%y%m%d%H%M");
sstream.imbue(std::locale(std::locale::classic(), facet));
sstream << submitPtime;
std::cout << "submit date:" << sstream.str( ) << std::endl;
}

How the time_point created with different duration(std::chrono::milliseconds and std::chrono::nanoseconds) is so different

I have created std::chrono::milliseconds ms and std::chrono::nanoseconds ns
from std::chrono::system_clock::now().time_since_epoch(). From that duration I created timepoints and convert it to time_t using system_clock::to_time_t and print it using ctime function. But the time printed is not same. As I understand the time_point have duration and duration have rep and period (ratio). So time_point must have same value up to millisecond precision in both time_points. Why the output is different?
Here is my code
#include <ctime>
#include <ratio>
#include <chrono>
#include <iostream>
using namespace std::chrono;
int main ()
{
std::chrono::milliseconds ms = std::chrono::duration_cast < std::chrono::milliseconds > (std::chrono::system_clock::now().time_since_epoch());
std::chrono::nanoseconds ns = std::chrono::duration_cast< std::chrono::nanoseconds > (std::chrono::system_clock::now().time_since_epoch());
std::chrono::duration<unsigned int,std::ratio<1,1000>> today_day (ms.count());
std::chrono::duration<system_clock::duration::rep,system_clock::duration::period> same_day(ns.count());
system_clock::time_point abc(today_day);
system_clock::time_point abc1(same_day);
std::time_t tt;
tt = system_clock::to_time_t ( abc );
std::cout << "today is: " << ctime(&tt);
tt = system_clock::to_time_t ( abc1 );
std::cout << "today is: " << ctime(&tt);
return 0;
}
This line:
std::chrono::duration<unsigned int,std::ratio<1,1000>> today_day (ms.count());
is overflowing. The number of milliseconds since 1970 is on the order of 1.5 trillion. But unsigned int (on your platform) overflows at about 4 billion.
Also, depending on your platform, this line:
std::chrono::duration<system_clock::duration::rep,system_clock::duration::period> same_day(ns.count());
may introduce a conversion error. If you are using gcc, system_clock::duration is nanoseconds, and there will be no error.
However, if you're using llvm's libc++, system_clock::duration is microseconds and you will be silently multiplying your duration by 1000.
And if you are using Visual Studio, system_clock::duration is 100 nanoseconds and you will be silently multiplying your duration by 100.
Here is a video tutorial for <chrono> which may help, and contains warnings about the use of .count() and .time_since_epoch().
The conversions you do manually do not look right.
You should use duration_cast for conversions because they are type-safe:
auto today_day = duration_cast<duration<unsigned, std::ratio<86400>>>(ms);
auto same_day = duration_cast<system_clock::duration>(ns);
Outputs:
today is: Thu Jul 26 01:00:00 2018
today is: Thu Jul 26 13:01:08 2018
Because you throw away the duration info, and then interpret an integer value as a different duration type
std::chrono::duration<unsigned int,std::ratio<1,1000>> today_day (ms.count());
milliseconds -> dimensionless -> 1 / 1000 seconds (i.e. milliseconds)
std::chrono::duration<system_clock::duration::rep,system_clock::duration::period> same_day(ns.count());
nanoseconds -> dimensionless -> system clocks
You should instead just duration_cast again
#include <ctime>
#include <ratio>
#include <chrono>
#include <iostream>
using namespace std::chrono;
int main ()
{
milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
nanoseconds ns = duration_cast<nanoseconds>(system_clock::now().time_since_epoch());
system_clock::time_point abc(duration_cast<system_clock::duration>(ms));
system_clock::time_point abc1(duration_cast<system_clock::duration>(ns));
std::time_t tt;
tt = system_clock::to_time_t ( abc );
std::cout << "today is: " << ctime(&tt);
tt = system_clock::to_time_t ( abc1 );
std::cout << "today is: " << ctime(&tt);
return 0;
}

How to Convert Custom string to ptime using boost

I have a string "2018Jan23T181138.65498648" which I need to convert to ptime. I have used below code but seems it is not working. Any idea what I am doing wrong here.
boost::posix_time::ptime pt;
std::istringstream is("2018Jan23T181138.65498648");
is.imbue(std::locale(std::locale::classic(), new boost::posix_time::time_input_facet("%Y%m%dT%H%M%S.%f")));
is >> pt;
std::cout << pt;
You need to at least match the format string to reflect the input format.
"Jan" is not a valid match for %Y%m%d (which would expect 20180123 instead). Likewise, %S.%f is a format string that might work for formatting¹, but to parse the seconds with fractions, the docs show to use %s
Live On Coliru
#include <boost/date_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <sstream>
#include <iostream>
int main() {
boost::posix_time::ptime pt;
std::istringstream is("2018Jan23T181138.65498648");
is.imbue(std::locale(std::locale::classic(), new boost::posix_time::time_input_facet("%Y%b%dT%H%M%s")));
if (is >> pt) {
std::cout << pt << "\n";
} else {
std::cout << "unparsed\n";
}
}
Prints
2018-Jan-23 18:11:38.654986
¹ haven't tested it for output formatting

std::get_time fails at midnight or noon using %I format specifier

When using std::get_time, I get an exception when parsing a datetime at midnight or noon. I am using the %I format specifier instead of %H because the hour should be between 1-12.
Exception: "ios_base::failbit set: iostream stream error"
I am using Microsoft Visual Studio 2013.
Why am I getting an exception when parsing this datetime? Is there a different format mask I can use?
#include <iostream>
#include <iomanip>
#include <ctime>
#include <cstring>
#include <sstream>
int main()
{
std::time_t time;
std::string timeString = "1/5/15 12:00 AM";
std::string formatMask = "%m/%d/%y %I:%M %p";
std::tm tm;
std::memset(&tm, 0, sizeof(std::tm));
std::istringstream ss(timeString);
ss.exceptions(std::ios::failbit | std::ios::badbit);
try
{
ss >> std::get_time(&tm, formatMask.c_str());
time = std::mktime(&tm);
}
catch (const std::exception& ex)
{
std::cout << ex.what() << std::endl;
}
std::cout << time << std::endl;
return 0;
}
ios_base::failbit generally means some logical error has occurred in processing the istringstream. Checking description of %I format it seems that the range seems wrongly specified here, it should be range [00,11] for a 12 hour clock IMO.
It should ideally work for 00:00 through 11:59 with Visual Studio 2013 compiler.
Thanks to #Cubbi posix specification does specify the range to be range [01,12] but so does MSVS2013.
The MSDN documentation for time_get::do_get specifies the range to be range[00,11] and this seems to be what std::get_time uses in VS2013 (#Cubbi found this).

chrono C++11 version of matlabs datenum

Is there a C++11 version of matlabs datenum function in #include<chrono>?
I already know it exists in boost thanks to this post
No, there is not. However here is a "how-to" manual for how to write the algorithms for your chrono-compatible date library. Using these algorithms, I can easily, for example, do this:
#include "../date_performance/date_algorithms"
#include <ratio>
#include <chrono>
#include <iostream>
typedef std::chrono::duration
<
int,
std::ratio_multiply<std::ratio<24>, std::chrono::hours::period>
> days;
typedef std::chrono::time_point<std::chrono::system_clock, days> date_point;
int
main()
{
using namespace std::chrono;
date_point datenum{days{days_from_civil(2014, 2, 5)}};
auto d = system_clock::now() - datenum;
auto h = duration_cast<hours>(d);
d -= h;
auto m = duration_cast<minutes>(d);
std::cout << "The current UTC time is " << h.count() << ':' << m.count() << '\n';
date_point datenum2{days{days_from_civil(2014, 3, 5)}};
std::cout << "There are " << (datenum2-datenum).count() << " days between 2014-03-05 and 2014-02-05\n";
}
Which for me outputs:
The current UTC time is 22:12
There are 28 days between 2014-03-05 and 2014-02-05
The first thing you need to do is create a chrono::duration to represent a day, named days above. Then it is handy to create a chrono::time_point based on the days duration. This time_point is compatible with every known implementation of system_clock::time_point. I.e. you can subtract them.
In this duration I subtract now() from the current date to get the hours::minutes of the day in the UTC timezone. I also demonstrate how to compute the number of days between any two dates.
Feel free to use these algorithms, and perhaps wrap all of this up in a type-safe date class. The link only provides the algorithms, and not an actual date class.
I might post a date class based on these algorithms in the future if I get the time...
I don't know what matlabs datenum is but here is how to do basically the same as the accepted answer of the question you link to, that is arithmetic with time points and durations but in C++11 without boost:
#include <chrono>
#include <iostream>
using namespace std;
using namespace std::chrono;
int main() {
duration<long> one_day{ hours(24) };
system_clock::time_point now = system_clock::now();
system_clock::time_point tomorrow = now + one_day;
time_t t = system_clock::to_time_t(tomorrow);
cout << "Tomorrow: " << ctime(&t) << '\n';
}
Hope this helps.

Resources