如何将自1970年以来的秒数转换为c ++中的DateTime?

时间:2011-02-02 10:49:43

标签: c++

如何将自1970年以来的秒数转换为c ++中的DateTime?
我正在以下面的格式获得时间:

1296575549:573352

冒号左侧部分为秒,右侧部分为微秒 请帮忙。

谢谢,
SYD

6 个答案:

答案 0 :(得分:4)

尝试并使用gmtime()(请参阅http://www.cplusplus.com/reference/clibrary/ctime/gmtime/)或localtime()将time_t转换为struct tm

答案 1 :(得分:3)

使用boost::Date_Time执行此操作。下面的代码假定_interval是自1970年以来的秒数。请注意,此代码示例不处理微秒部分,但我确信可以对其进行修改。

#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));

答案 2 :(得分:2)

使用C / C ++库转换时间的三个重要事项。

    来自标准库的
  1. gmtime()localtime()从time_t转换为struct tm,但time_t的分辨率是epoch的秒数。所以小数秒不算数。

  2. mktime()从struct tm向后转换为time_t,但如果输入日期超出范围,则返回-1。 (参考:year 2038 problem

  3. 如果你没有使用64位时间戳,即使你在64位机器上运行程序,你仍然有2038年的问题。有一些64位版本的功能,例如gmtime64()localtime64()mktime64(),可以解决年度超出范围的问题。 (Reference

答案 3 :(得分:1)

嗯,最复杂的案例:

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

要计算当天的月份,您需要复制粘贴isLeapYear函数,因为2月份。

嗯,看起来人们还需要考虑闰年直到最后一个闰年,这些都是在盈余中扣除的。嗯,夏令时的影响...

去睡觉!

答案 4 :(得分:0)

作为持续时间的示例,我们假设您想知道程序的运行时间:

#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 );

例如,你会得到类似的东西:

elapsed time: 01h 02m 14s

答案 5 :(得分:0)

一个非常老的问题的新答案。原理:更好的工具。

从C ++ 11开始,您可以轻松地将此数量存储在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}};
}

尽管在C ++ 11中未指定system_clock的时期,但是每个实现都在跟踪Unix Time(自1970-01-01 00:00:00 UTC以来的时间,不包括leap秒)。不同的实现对system_clock::time_point具有不同的精度,但是如上所述,当转换为system_clock::time_point时,您实际上不必关心它。 <chrono>库将做正确的事情。

从C ++ 20开始,将指定system_clock::time_point的{​​{3}}度量,您将能够以易于理解的形式将其流式传输出来:

cout << tp << '\n';

对于此示例,将输出:

2011-02-01 15:52:29.573352

在某些平台上,此输出上可能会有一些尾随零,具体取决于该平台上system_clock::time_point的精度。这是UTC日期/时间。如果需要的话,还将有一些方法可以将其转换为特定的时区(在C ++ 20中)。

您现在可以使用Unix Time来试用C ++ 20的这一部分。这将需要一个额外的#include "date/date.h"(用于时区功能的"date/tz.h")和一个using namespace date;来启用system_clock::time_point流操作符。

如果知道您的秒数包括leap秒(Unix时间戳记不包括),则C ++ 20还提供了一种处理方法:

只需在上面的示例中将system_clock更改为utc_clock,新的输出将是:

2011-02-01 15:52:05.573352

表示在此日期之前插入的24 leap秒。