How can I convert number of seconds since 1970 to DateTime in c++?
I am getting the time in the below format:1296575549:573352
The left part of the colon is in seconds and the right part in micro seconds.
Please he开发者_开发百科lp.Thanks,
SydTry and use gmtime() (see http://www.cplusplus.com/reference/clibrary/ctime/gmtime/) or localtime() to convert a time_t to a struct tm
Use boost::Date_Time to do this. Code below assumes _interval
is number of seconds since 1970. Note this code example doesn't handle the micro-second portion, but I am sure it could be modified to do so.
#include <boost/date_time/gregorian/gregorian_types.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
double interval(1296575549.0f);
boost::posix_time::ptime m_DateTime = ptime(date(1970, 1, 1),
time_duration(0, 0, 0,
time_duration::ticks_per_second() *
(time_duration::fractional_seconds_type)_interval));
Three important things about converting time using C/C++ library.
gmtime()
orlocaltime()
from standard library convert from time_t to struct tm, but the resolution for time_t is seconds from epoch. So fractional seconds will not count.mktime()
converts backwards from struct tm to time_t, but it will return -1 if the input date is out of range. (Reference: year 2038 problem)If you are not using 64bit timestamp, even you run programs on 64bit machines, you still have year 2038 problem. There are 64bit version functions like
gmtime64()
,localtime64()
,mktime64()
that may resolve the year out of range issue. (Reference)
New answer for a very old question. Rationale: Better tools.
Starting in C++11, one can easily store this quantity in a std::chrono::system_clock::time_point
:
#include <chrono>
#include <iostream>
#include <sstream>
int
main()
{
using namespace std;
using namespace std::chrono;
istringstream in{"1296575549:573352"};
long si, usi;
char sep;
in >> si >> sep >> usi;
system_clock::time_point tp{seconds{si} + microseconds{usi}};
}
Though the epoch of system_clock
is unspecified in C++11, every implementation is tracking Unix Time (time since 1970-01-01 00:00:00 UTC, excluding leap seconds). Different implementations will have different precisions for system_clock::time_point
, but you don't really have to care about that when converting into system_clock::time_point
as shown above. The <chrono>
library will just do the right thing.
Starting in C++20 the Unix Time measure of system_clock::time_point
will be specified, and you will be able to stream it out in a human readable form:
cout << tp << '\n';
For this example that will output:
2011-02-01 15:52:29.573352
On some platforms there may be a few trailing zeroes on this output, depending on the precision of system_clock::time_point
on that platform. This is a UTC date/time. There will also be ways to convert this to a particular time zone if desired (in C++20).
You can experiment with this part of C++20 today by using Howard Hinnant's date/time library. This will require an additional #include "date/date.h"
("date/tz.h"
for time zone functionality), and a using namespace date;
to enable the system_clock::time_point
streaming operator.
If it is known that your count of seconds includes leap seconds (Unix Time stamps don't), C++20 also provides a way to deal with that:
Just change system_clock
to utc_clock
in the above example and the new output will be:
2011-02-01 15:52:05.573352
which accounts for the 24 leap seconds inserted prior to this date.
As an example of duration available in seconds, let's assume you want to have an idea of the running time of your program:
#include <ctime>
time_t startRawTime;
time( &startRawTime );
//...your program performs computations...
time_t endRawTime;
time( &endRawTime );
time_t elapsedSec = difftime( endRawTime, startRawTime );
// but elapsedSec can be any duration, e.g. 3734, as long as it is in seconds
tm * ptm = gmtime( &elapsedSec );
printf( "elapsed time: %02dh %02dm %02ds\n",
ptm->tm_hour,
ptm->tm_min,
ptm->tm_sec );
You would get something like this for instance:
elapsed time: 01h 02m 14s
Well, the most complex case:
86'400 s/day
31'557'600 s/year (365.25 d)
1296575549/31557600 = 41 years
1296575549-41*31557600 = 2'713'949 s
2713949/86400 ==> 31 d
2713949-31*86400 =35'549
35549/(60*60) = 9h
35549-9*60*60 = 3'149
3'149/(60*60) = 0h
3'149- 0* (60*60) = 3'149
3149/60 = 52 m
3149-52*60 = 29s
--> year = 1970 + 41
--> month = 1 + 0
--> day = 31 (+1?)
--> Time 00:52:29
==> 2011, Jan 31, 00:52:29 GMT
To calculate the month from the day, you need to copy paste an isLeapYear function, because of February.
Hmm, looks like one also needs to account for the leap years until last leap year, which were subtracted in surplus. Hmm, effects of daylight saving time...
Go sleep !
精彩评论