根据输入数据的数量,我有一个可以在几秒钟或几天内运行的程序。在程序结束时,我想打印经过的“时钟墙”时间:如果小于一分钟,则以秒为单位;如果小于一小时,则以分秒为单位;如果小于一小时,则以时分秒为单位。少于一天,否则以天时分秒为单位。这是我正在使用的代码:
#include <cstdio>
#include <ctime>
#include <unistd.h> // for sleep
int main (int argc, char ** argv)
{
time_t startRawTime, endRawTime;
time (&startRawTime);
printf ("%s", ctime (&startRawTime));
sleep (3); // any preprocessing of input data
time (&endRawTime);
printf ("%s", ctime (&endRawTime));
printf ("%.0fs\n", difftime (endRawTime, startRawTime));
time_t elapsed = static_cast<time_t>(difftime (endRawTime, startRawTime));
struct tm * ptm = gmtime (&elapsed);
printf ("%id %ih %im %is\n", ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
return 0;
}
这是打印的内容:
Mon Apr 9 14:43:16 2012
Mon Apr 9 14:43:19 2012
3s
1d 0h 0m 3s
当然,最后一行是错误的(应该为“ 0d”)。看来可以通过打印
ptm->tm_mday - 1
轻松解决。但是,当两个日期之间确实经过了一天时,ptm->tm_mday
也将为“ 1”。因此,在那种情况下,我不想使其显示为“ 0d”。那么有没有办法正确处理呢?还是我应该将
difftime
的结果作为双精度值(即秒数),然后计算自己的秒/分钟/小时/天数?备注:我的代码仅在使用
gcc -lstdc++
编译的Linux上使用。 最佳答案
time_t
值表示特定的时刻。 difftime
的结果是两分钟之间的时间间隔(以秒为单位)。那是完全不同的事情。
在您的代码中,difftime()
返回3.0
,因为两个指定时间之间有3秒。将其转换为time_t
会在纪元后3秒钟给您一点时间;在大多数系统上,这将是格林尼治标准时间1970年1月1日午夜3秒钟之后。tm_mday
值为1,因为那是该月的第一天。
您可以通过从tm_mday
值中减去1来实现此目的,因为tm_mday
是基于1的,而不是基于0的。但是在更长的时间间隔内,您仍然会获得毫无意义的结果。例如,间隔31.5天将使您在2月1日中午,因为1月为31天;与您要获取的信息无关。
只需将difftime()
的结果视为double
(因为它就是这样),然后通过简单的算术计算天数,小时数,分钟数和秒数。
(由于失去了可移植性,您可以直接对time_t
值进行求和,而不是使用difftime()
。这会使某些算法更容易一些,但是在time_t
值与其他值不同的系统上会破坏距某个纪元以来的整数秒数。difftime()
存在是有原因的。)
当然,最后一行是错误的(应该为“ 0d”)。看来可以
通过打印“ ptm-> tm_mday-1”可以轻松解决。但是,ptm-> tm_mday
如果两者之间确实有一天过去了,则也将为“ 1”
日期。因此,在那种情况下,我不想使其显示为“ 0d”。
那是不对的。如果时间间隔刚好超过1天,则ptm->tm_mday
将为2
。您可以通过对代码进行少量修改来验证这一点:
time (&endRawTime);
endRawTime += 86400; // add this line
printf ("%s", ctime (&endRawTime));
进行更改时,将得到以下输出:
Mon Apr 9 13:56:49 2012
Tue Apr 10 13:56:52 2012
86403s
2d 0h 0m 3s
可以通过从
ptm->tm_mday
减去1来更正。但这又不是正确的方法。