15

我正在寻找一种在 C++ 中以 HH::MM::SS 方式节省时间的方法。我在这里看到它们有很多解决方案,经过一番研究后,我选择了timeand localtime。但是,该功能似乎localtime有点棘手,因为它

所有对 localtime 和 gmtime 的调用都使用相同的静态结构,因此每次调用都会覆盖前一次调用的结果。

这导致的问题显示在下一个代码片段中:

#include <ctime>
#include <iostream>
using namespace std;

int main() {
time_t t1 = time(0);   // get time now
struct tm * now = localtime( & t1 );

std::cout << t1 << std::endl;
sleep(2);
time_t t2 = time(0);   // get time now
struct tm * now2 = localtime( & t2 );
std::cout << t2 << std::endl;

cout << (now->tm_year + 1900) << '-'
     << (now->tm_mon + 1) << '-'
     <<  now->tm_mday << ", "
     << now->tm_hour << ":" << now->tm_min << ":" << now->tm_sec
     << endl;

cout << (now2->tm_year + 1900) << '-'
     << (now2->tm_mon + 1) << '-'
     <<  now2->tm_mday << ", "
     << now2->tm_hour << ":" << now2->tm_min << ":" << now2->tm_sec
     << endl;
}

一个典型的输出是:

1320655946
1320655948
2011-11-7, 9:52:28
2011-11-7, 9:52:28

正如你所看到的,time_t时间戳是正确的,但是本地时间把一切都搞砸了。

我的问题是:如何将时间戳 ot 类型time_t转换为人类可读的时间?

4

4 回答 4

20

如果你担心 and 中的重入localtimegmtimelocaltime_randgmtime_r 可以处理多个调用。

在根据自己的喜好格式化时间时,请检查功能strftime

于 2011-11-07T09:10:07.760 回答
4

localtime() 调用将结果存储在内部缓冲区中。

每次调用它时,都会覆盖缓冲区。
另一种解决方案是制作缓冲区的副本。

time_t      t1  = time(0);           // get time now
struct tm* now  = localtime( & t1 ); // convert to local time
struct tm  copy = *now;              // make a local copy.
 //     ^^^ notice no star.

但请注意:您应该转换为本地时间的唯一时间是显示值时。在所有其他时间,您应该将时间保持为 UTC(用于存储和操作)。由于您只是将对象转换为显示转换然后立即打印,然后事情就不会出错。

于 2011-11-07T10:13:44.420 回答
0

localtime具有最好的遗留接口。例如,它不能用于多线程代码。在多线程环境中,您可以localtime_r在 Posix 或localtime_s Windows 下使用。否则,您所要做的就是保存结果:

tm then = *localtime( &t1 );
//  ...
tm now = *localtime( &t2 );

但是,仅localtime
在格式化输出之前立即调用可能会更惯用,例如:

std::string
timestampToString( time_t timeAndDate )
{
    char results[100];
    if ( strftime( results, sizeof( results ), "%Y-%m-%d, %H:%M:%S", 
                localtime( &timeAndDate) ) == 0 ) {
        assert( 0 );
    }
    return results;
}

然后写:

std::cout << formatTime( t1 ) << std::endl;

(您还可以创建一个更通用的格式化函数,将格式作为参数。)

于 2011-11-07T10:24:19.730 回答
-1

您可以使用以下代码运行连续时钟。它工作得很好。

#include<iostream> 
#include <Windows.h> 
#include<ctime> 
using namespace std;

void main() {
  while(true) {
    system("cls"); //to clear screen
    time_t tim;
    time(&tim); 
    cout << ctime(&tim); 
    Sleep(1);
  }
}
于 2014-07-03T10:09:35.860 回答