我使用以下命令从文本文件中解析日期时间:
#define DATETIME_FORMAT "%Y-%m-%d %H:%M:%S"
if (!strptime(datetimestr, DATETIME_FORMAT, &record->datetime)) {
return 0;
} else {
record->message_size = strlen(messagestr) - 1;
messagestr[record->message_size] = '\0';
strcpy(record->message, messagestr);
printf("parsed '%s' '%s' %ld\n", messagestr, datetimestr, mktime(&record->datetime));
return 1;
}
我得到了这些指纹
parsed 'ETC' '2023-04-03 09:00:19' 1680508819
parsed 'StandUp' '2023-04-03 09:00:47' 1680508847
parsed 'Stop' '2023-04-03 09:11:55' 1680505915
但是当我将它们粘贴到online epoch converter时,我得到了:
- 1680508819 =〉GMT:周一3.四月2023 8:00:19
- 1680508847 =〉GMT:周一3.四月2023 8:00:47
- 1680505915 =〉GMT:周一3.四月2023 7:11:55
那么,为什么strptime
和mktime
转换第三次约会完全不同呢?
2条答案
按热度按时间68de4m5k1#
为什么strptime和mktime转换第三次约会完全不同?
当
struct tm
未完全分配时,mktime()
可能会出现不一致的行为。strptime(datetimestr, DATETIME_FORMAT, &record->datetime)
填充record->datetime
的struct tm
成员中的 * 一些 *。tm should be initialized before the call.mktime()
使用由strptime(..., %Y-%m-%d %H:%M:%S", ...
分配的成员以及包括.tm_isdst
在内的其他成员,这些成员占用一个小时。在
strptime()
之前,对整个struct tm
进行零填充 *1,并将.tm_isdst
设置为-1
(让mktime()
确定DST设置)。联系我们旁白:使用匹配的打印说明符。
"%ld"
可能不匹配time_t
。建议转换为宽类型。请注意,
mktime()
将struct tm
读取为 * 本地 * 时间,而不是GMT或UTC。struct tm
* 至少 * 9个成员。2(.tm_yday
,.tm_wday
)在确定返回time_t
时被gmtime()
忽略。由于各种实现可能有超过9个标准成员,因此我们希望初始化/分配 * 所有 * 成员以获得一致的结果。struct tm tm = { 0 };
或memset(&tm, 0, sizeof tm);
是两种方法。strptime(datetimestr, %Y-%m-%d %H:%M:%S", &record->datetime)
设置6个预期成员(以及.tm_yday
、.tm_wday
),但不设置.tm_isdst
,也不可能设置其他tm
成员。代码可以零初始化并设置
.tm_isdst
:代码可以用 * 复合文字 * 分配
.tm_isdst
和零个其他成员。cs7cruho2#
1.初始化
struct tm
。strptime()
返回NULL或指向解析器停止位置的指针。如果它是NULL或者它没有指向\0
,那么可能是一个错误。1.修剪
messagestr
最后一个字符的方式是有问题的。如果要修剪换行符,请使用messagestr[strcspn(messagestr, "\n")] = '\0';
。我无法用以下最小的例子来重现你的发现。请让我知道你使用的是什么时区(TZ),以及最后一个日期时间字符串的结果。
下面是相应的输出: