如何正确使用 ctime() 打印不同的时间戳

Posted

技术标签:

【中文标题】如何正确使用 ctime() 打印不同的时间戳【英文标题】:how to correctly use ctime() to print different time stamps 【发布时间】:2016-08-23 23:41:13 【问题描述】:

我原以为下面的代码应该打印不同的时间戳 t1 和 t2,但是结果显示 t1 和 t2 是相同的。我在哪里犯了错误?

#include<iostream>
#include<ctime>

using namespace std;

int main()

    time_t t1 = time(NULL);
    cout << "time now " << ctime(&t1) << endl;
    time_t t2 = t1 + 10000.0;
    cout << "time now " << ctime(&t1) << endl << " time later " << ctime(&t2) <<endl;

结果:

time now Thu Apr 28 20:37:03 2016

time now Thu Apr 28 20:37:03 2016

 time later Thu Apr 28 20:37:03 2016

【问题讨论】:

PS:根据下面的精彩答案,问题应该与 ctime() 函数的工作方式和编译器评估 cout 参数的顺序有关。后者可以参考***.com/questions/12960241/…的例子 【参考方案1】:

你的问题的答案可以在the manual page for the ctime() function找到:

返回值指向一个静态分配的字符串,它可能 被后续调用任何日期和时间覆盖 功能。

ctime() 返回一个指向它使用的内部缓冲区的指针。每次调用它都会返回一个指向同一个缓冲区的指针:

 cout << "time now " << ctime(&t1) << endl << " time later " << ctime(&t2) <<endl;

对于这行代码,您的编译器生成的代码调用ctime() 两次,然后执行&lt;&lt; 运算符。但是在第二次调用ctime() 时,它第二次覆盖了缓冲区,所以当&lt;&lt; 运算符格式化输出时,因为第一次调用ctime() 的结果是同一个指针,而缓冲区它指向的已被第二次调用ctime() 覆盖,您会得到相同的时间打印两次。

感谢您发布Minimal, Complete, and Verifiable example。

【讨论】:

【参考方案2】:

ctime 实际返回的是什么?来自cppreference:

指向以空字符结尾的静态字符串的指针,该字符串包含日期和时间的文本表示。 字符串可以在std::asctimestd::ctime 之间共享,并且可以在每次调用这些函数时被覆盖。

很可能在您的编译器上,先调用较晚的ctime(),然后调用较新的ctime(),然后评估两个operator&lt;&lt;()——它们发出相同的char*。由于未指定顺序,您的代码具有未定义的行为。在某些编译器上,它可以像您希望的那样工作!在你的身上,它恰好不是。

如果你把这两个电话分开:

cout << "time now " << ctime(&t1) << endl;
cout << " time later " << ctime(&t2) <<endl;

您肯定会始终如一地看到不同的价值观。

【讨论】:

【参考方案3】:

引自N1570 7.27.3 时间转换函数:

除了 strftime 函数,这些函数都返回一个指向两个函数之一的指针 静态对象类型:分解的时间结构或字符数组。执行 返回指向这些对象类型之一的指针的任何函数都可能覆盖 由 any 返回的值所指向的任何相同类型的对象中的信息 以前调用它们中的任何一个,并且不需要这些函数来避免与 彼此。

这表明ctime() 返回的内容所指向的内容可以被另一个ctime() 调用覆盖,因此您必须复制结果以在一个没有序列点的表达式中使用该结果。

试试这个:

#include<iostream>
#include<ctime>
#include<string>

using namespace std;

int main()

    time_t t1 = time(NULL);
    cout << "time now " << ctime(&t1) << endl;
    time_t t2 = t1 + 10000.0;
    string t1s = ctime(&t1);
    string t2s = ctime(&t2);
    cout << "time now " << t1s << endl << " time later " << t2s <<endl;

【讨论】:

以上是关于如何正确使用 ctime() 打印不同的时间戳的主要内容,如果未能解决你的问题,请参考以下文章

如何以正确的格式获取 UTC 偏移量(时区)?

Linux时间戳atime ctime mtime区别及相关命令

如何在python中获取印度的当前时间

Python系列之模块

使用python获取当前的时间

使用python获取当前的时间