c/c++ strptime() 不解析 %Z 时区名称 [英] c/c++ strptime() does not parse %Z Timezone name

查看:50
本文介绍了c/c++ strptime() 不解析 %Z 时区名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 C 的新手.当我练习 C 以隐藏时间刺痛来来回构建 tm 时.我注意到了一些不同.请指教我做错了什么.

I am new to C. When I practicing C to covert time sting to structure tm back and forth. I noticed some difference. Please advice what I did wrong.

#include <string.h>
#include <stdio.h>
#include <time.h>

/* 
test different format string to strptime
" %A, %b %d, %X %z %Y "
" %A, %b %d, %X %Z %Y "
*/
int main(int argc,char *argv[])
{

   char date[] = "6 Mar 2001 12:33:45";
   char fmt[80];
   struct tm tm;

   if (argc==1) return 0;
   strcpy(fmt,argv[1]);
   memset(&tm, 0, sizeof(struct tm));
   if (strptime(date,"%d %b %Y %H:%M:%S",&tm)==NULL) printf("error\n");
   char buf[128];
   strftime(buf, sizeof(buf), fmt, &tm);
   printf("%s\n", buf);
   printf("%d\n", tm.tm_isdst);
   if (strptime(buf,fmt,&tm)==NULL) printf("error\n");
   else {
   printf("year: %d; month: %d; day: %d;\n",
         tm.tm_year, tm.tm_mon, tm.tm_mday);
   printf("hour: %d; minute: %d; second: %d\n",
         tm.tm_hour, tm.tm_min, tm.tm_sec);
   printf("week day: %d; year day: %d\n", tm.tm_wday, tm.tm_yday);
   }
   return 0;
}

当我使用"%A, %b %d, %X %z %Y "作为转换格式参数时,代码提供了一些结果如下:

When I use " %A, %b %d, %X %z %Y " as conversion format argument, the code provide some result as follow:

 ~/user$ ./test_time " %A, %b %d, %X %z %Y "
 Tuesday, Mar 06, 12:33:45 +0000 2001 
 0
 year: 101; month: 2; day: 6;
 hour: 12; minute: 33; second: 45
 week day: 2; year day: 64

当我将参数更改为"%A, %b %d, %X %Z %Y "时,代码无法解析由 strftime 生成的具有完全相同格式的时间字符串.

When I change argument to " %A, %b %d, %X %Z %Y ", the code can not parse the time string which is generated by strftime with exactly the same format.

 ~/user$ ./test_time " %A, %b %d, %X %Z %Y "
  Tuesday, Mar 06, 12:33:45 EET 2001 
 0
 error

我是否错过了让 strptime 正确解析时区名称的内容?

Did I miss something to let strptime parse timezone names correctly?

提前致谢,

阿尔伯特

推荐答案

我不确定你正在做的事情是否会奏效.github 上的 glibc 源代码 对此有这样的说法:

I'm not sure what you're doing will work. The glibc source code at github has this to say on the matter:

case 'Z':
    /* XXX How to handle this? */
    break

接下来是对小写 'z' 的一些稍微肉"的处理:-)

followed by some slightly more "meaty" handling of the lowercase 'z' stuff :-)

所以这里最有可能发生的情况是,当格式字符串为 %Z 时,字符串指针没有超过 EET,因此当它尝试处理时%Y,它理所当然地抱怨 EET 不是有效年份."%%" 的简单情况证实了这一点,其中代码实际上确实推进了输入字符串指针 rp:

So what's most likely happening here is that the string pointer isn't advancing past the EET when the format string is %Z, so that when it tries to process %Y, it complains, rightly so, that EET is not a valid year. This is confirmed by the simple case of "%%" where the code actually does advance the input string pointer rp:

case '%':
    /* Match the `%' character itself.  */
    match_char ('%', *rp++);
    break;

Linux 手册页还说明了扩展(其中 'Z' 是其中之一):

The Linux man page also states on the extensions (of which 'Z' is one):

出于对称的原因,glibc 尝试支持 strptime() 与 strftime(3) 相同的格式字符.(大多数情况下会解析相应的字段,但不会更改 tm 中的字段.)

For reasons of symmetry, glibc tries to support for strptime() the same format characters as for strftime(3). (In most cases the corresponding fields are parsed, but no field in tm is changed.)

此外,GNU 文档 状态(我的斜体):

In addition the GNU docs state (my italics):

%Z: 时区名称.注意:目前,这还没有完全实现.格式被识别,输入被消耗但没有设置 tm 中的字段.

%Z: The timezone name. Note: Currently, this is not fully implemented. The format is recognized, input is consumed but no field in tm is set.

所以我实际上认为这是一个错误,尽管可以通过更改文档轻松修复这个错误,以停止假装它可以处理 Z 类型的时区.

So I actually consider this a bug, albeit one that can be easily fixed with a documentation change to stop pretending it can handle Z-type timezones.

我在 bugzilla 中找不到任何相关的错误,所以我在 glibc 上提出了一个错误.您可以在此处进行跟踪.

I cannot find any relevant bug in bugzilla so I've raised a bug on glibc there. You can track it here.

附录:根据上一段中的错误报告链接和 glibc 2.19 发布通知,我建议进行更改以使代码与文档保持一致.希望它没有错误,否则我会看起来很傻,因为它只有五行代码.

Addendum: as per the bug report link in the previous paragraph and the glibc 2.19 release notice, the change I suggested has been made to align the code with the documentation. Hopefully, there's no bugs in it or I'm going to look pretty silly given it's only five lines of code.

这篇关于c/c++ strptime() 不解析 %Z 时区名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆