在Linux上严格解析YYYY-MM-DD日期

时间:2012-10-24 19:45:37

标签: linux posix strptime

POSIX定义了一个方便的函数strptime,可用于解析日期和时间。因此,从理论上讲,如果我的日期格式为“YYYY-MM-DD”,我应该可以使用strptime来解析它:

char myDate[] = "2012-01-01";

struct tm result;
char *end = strptime(myDate, "%Y-%m-%d", &result);

...并使用以下标准将其恢复为规范表示:

if (end != NULL)
{
    char outDate[11];
    strftime(outDate, sizeof(outDate), "%Y-%m-%d", &result);
    printf("%s\n", outDate);
}
else
    printf("Invalid date\n");

在OS X和Linux上,打印出2012-01-01。到现在为止还挺好!但是,假设输入日期格式错误:01-01-2012。

如果我再次运行上面的代码,在OS X上,我得到“无效日期”,这是预期的。但是,在Linux上,我得到1-01-20 - 1月20日,1(是的,第一年)。

OS X严格遵循说明符,仅将字符串解析为%Y ,其中存在四位数年份。然而,Linux需要一些自由,并且将两位数解释为一年 - 它甚至看起来它假设它是2001年,它将它视为第1年!

这可以通过将我的if语句更改为类似

来解决
if (end != NULL && *end == '\0')

......但这似乎很糟糕。有没有人知道是否可以使Linux上的strptime表现得更严格,如果输入字符串没有四位数年份,则%Y会失败?

2 个答案:

答案 0 :(得分:2)

没有选项可以更改strptime()的行为或指定格式字符串中的长度。 (我查看了glibc-2.3中的源代码,strptime丢弃格式修饰符和字段宽度,所以“%04Y”之类的东西不会改变。)

但正如评论中已经指出的那样,if (end != NULL && *end == '\0')没有任何问题。我建议只使用它。

答案 1 :(得分:0)

我猜你最好的办法是找到第一个短划线的索引,并根据其值使用一个掩码或另一个掩码。