开发者

How can I convert number of seconds since 1970 to DateTime in c++?

开发者 https://www.devze.com 2023-02-07 21:58 出处:网络
How can I convert number of seconds since 1970 to DateTime in c++? I am getting the time in the below format:

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,

Syd


Try 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.

  1. gmtime() or localtime() 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.

  2. 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)

  3. 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 !

0

精彩评论

暂无评论...
验证码 换一张
取 消