Bruce Coghill 写道:
> 在我的C手册中,time.h和time函数被描述了
> 以及我如何提取结构中的每个元素(如年、
> 月、日、一年中的第几天),但我不清楚如何减去
> 一天。
这是FAQ列表中的第13.14个问题,但我想在它所说的基础上扩展一点。
Bruce,你已经进行到了调用time()和localtime()。下一步是利用mktime()的规范化功能。假设你有一个类型为struct tm的变量,名为x,并且你刚刚用localtime()将其填充为当前时间。现在你基本上只需要做类似这样的事情:
x.tm_day--; /* back 1 day */ (void) mktime (&x); /* normalize */
很可能有人会回复建议这样做。上面的代码在大多数情况下都会起作用,但有两个问题。首先,mktime()可能会失败,所以最好检查它并报告错误。
其次,它找到的是24小时前的时间。如果发生了夏令时转换,24小时前可能是今天或前天。
你可能会想通过添加以下行来修复第一个问题:
x.tm_isdst = -1;在开头,有效地强制mktime()按时钟时间工作。现在你要求的是昨天相同的时刻,而不是24小时前的时间。但这并没有解决问题——在夏令时转换的情况下,“昨天相同的时刻”可能不明确或不存在。在这种情况下,mktime()的失败是允许的(或者可能被要求,取决于如何解释标准)。
正确的修复方法是让夏令时转换生效,通过保持tm_isdst不变,但要求获取今天中午附近某个时间点24小时之前的时间。即使那个时间点是上午11点或下午1点,它仍然会是昨天。所以最终版本的代码是:
x.tm_day--; /* back 1 day (well, 24 hours) */ x.tm_hour = 12; /* from some time between noon and 1 pm */ /* and normalize */ if (mktime (&x) == (time_t) -1) { fprintf (stderr, "mktime failed!!\n"); exit(1); }
现在该结构包含了正确的年、月和日值,代表昨天。一如既往,请记住,表示struct tm需要将年份加1900,将月份加1,才能得到正确的数值。
有一个更简洁的“最终”代码版本:将前两行替换为:
x.tm_hour = -12; /* 12 hours before sometime between * midnight and 1 am this morning */但其含义不太明显,所以我不推荐。
-- Mark Brader "To err is human, but to really mess things up msb@sq.com you need a timetable planner!" SoftQuad Inc., Toronto -- Richard Porter
本文中的我的内容属于公共领域。