我正在使用strptime(3)
解析表示日期的字符串:
#include <time.h>
#include <stdio.h>
int main () {
struct tm t;
strptime("2015-04-19 12:00:00", "%F %T", &t); /* Sunday */
printf("%d\n", t.tm_wday); /* Should print 0 */
return 0;
}
根据
cal -y 2015
的输出,该日期是星期日。但是,当我在OSX(大概是用clang)上编译它时,它会打印6
:$ gcc timetest.c ; ./a.out
6
而在Debian上,它会打印(正确的)
0
:$ gcc timetest.c ; ./a.out
0
有什么区别的解释吗?
更新
这是同一程序,除了
t
用有效时间初始化并且我正在报告strptime()
的返回值:#include <time.h>
#include <stdio.h>
int main () {
time_t epoch = 0;
struct tm t;
char *ret;
t = *localtime(&epoch);
ret = strptime("2015-04-19 12:00:00", "%F %T", &t); /* Sunday */
printf("%d\n", t.tm_wday); /* Should print 0 */
printf("strptime() returned %p (%d)\n", ret, *ret);
return 0;
}
这是输出:
$ gcc timetest.c ; ./a.out
6
strptime() returned 0x10c72af83 (0)
这是我使用的
clang
版本:$ clang -v
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin16.1.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
最佳答案
我认为原因仅仅是设计上的the strptime
function only sets the fields that appear in the format。本质上,strptime(3)
只是使用提供的格式将给定字符串中的字段解析为引用的结构,并且不执行其他任何计算或逻辑。由于您的代码使用%F %T
格式,因此仅修改了与%Y-%m-%d
和%H:%M:%S
(即tm_{year,mon,mday,hour,min,sec}
)相对应的字段。
您可以通过将t.tm_wday
显式设置为strptime
不应设置的某个已知值(例如123)进行实验,并验证该调用不会更改它。请注意,您可能应该在使用struct tm
之前对其进行初始化,因为这些字段中的任何一个都可能包含随机值,例如struct tm t; memset((void *) &t, 0, sizeof(t));
。
此外,此Linux strptime(3)
man page包含以下注释,这使我相信它描述的特殊行为是非标准的(尽管显然是可取的):
glibc实现不涉及那些未明确指定的字段,只是如果更改了年,月或日元素中的任何一个,它将重新计算tm_wday
和tm_yday
字段。
This answer shows how您可以使用strptime/mktime/localtime
(或gmtime
)三重奏为UNIX时代之后的日期填充tm.tm_wday
字段。
关于c - 为什么在本例中strptime()不能正确设置tm_wday?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40764356/