strftime和非规范化日期/时间

4
大多数 strftime 的定义中,包括 ANSI/ISO C 标准中的 %H%M%S 指示符,都会包含如下语言:

%H 会被替换为小时(24 小时制)的十进制数字(00-23)。

现在,这个小注释 "(00-23)" 告诉你,如果你要打印的 struct tm 刚刚是由 localtimegmtime 创建的,你将会看到哪些数字范围。
我的问题涉及到一个要求的存在或缺失,即引用 strftimestruct tm 必须是由 localtimegmtime 刚刚生成的。我认为并没有这样的要求,但如果没有的话,那些注释 "(00-23)" 和 "(00-59)" 对于 strftime 实际上并没有任何规范意义——它们更像是对由 localtimegmtime 生成的值的错误要求。
但如果 strftime 不限制各种 struct tm 字段的范围到它们的“正常”值,那么当调用 strftime 时,一个推动边界的程序员实际上有多少自由度呢?这些值与调用 mktime 时一样无限吗?
为了更具体地说明问题,当我写下以下代码时,这个问题就出现了:
time_t dt = t2 - t1;
struct tm *tmp = gmtime(&dt);
if(dt > 86400)
    tmp->tm_hour += dt / 86400 * 24;
strftime(etbuf, sizeof(etbuf), "elapsed: %H:%M:%S", tmp);

也就是说,我正在减去两个时间,并让gmtimestrftime将差异转换为HH:MM:SS格式。但如果时间差超过一天,我不会将其打印为天数;我只是将其与小时合并(如果在t1t2之间有几个月或几年,则可能会得到非常大的数字)。
因此,语言法律问题:这是否合法和可移植?在调用strftime时,tm_hourtm_min和其他内容是否限制在它们的正常范围内?
(是的,我已经尝试过了,非规范化的值可以工作--毫不奇怪--在流行的实现下按预期工作,但这不是问题。)
[完整披露:我正在将same question发布到tz邮件列表。]

99以上的值可以正常工作吗? - Retired Ninja
@RetiredNinja 是的。 - Steve Summit
1个回答

4
C11标准7.27.3.5/3规定:
如果指定的任何值超出正常范围,则存储的字符是未指定的。
我认为这意味着输入必须被规范化,以便函数正确地执行;并且符合规范的strftime实现可能会通过简单地读取和显示存储在结构体中的值而不对其进行任何分析来操作。

1
谢谢您的查看。我有点失望,但并不意外。至少它不是未定义的。 - Steve Summit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接