PHP的strptime格式错误? [英] PHP strptime format bug?

查看:270
本文介绍了PHP的strptime格式错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在与一个PHP 5.2.6的问题摔跤。我们使用的api返回日期格式为DDMMYYYYHHMM。确切的说,这个格式,固定长度,没有分隔符。然而,在我的实验中,这种格式似乎打破了strptime,当我以这种格式提供日期时,它返回一个错误(失败)。至少在我的系统中,可以用这个例子来复制它:

  $ format =%d%m%Y%H %M; echo print_r(strptime(strftime($ format,1225405967),$ format),true); 

如果我在日期和时间之间添加任何字符,它将起作用,甚至是空格。所以,这个工作:

  $ format =%d%m%Y%H%M; echo print_r(strptime(strftime($ format,1225405967),$ format),true); 

我缺少一些明显的东西吗?

编辑:除此之外,由于评论的结果,这似乎是平台特定的。我可以在办公室里运行OSX Leopard的Mac上复制它,但是Linux的盒子解析得很好。我认为这是OSX * nix底层C库中strptime的一个bug或特性。

解决方案

认为问题出在MacOS X和C库上,那么你可以生成一个测试用例来演示它。例如,我在MacOS X 10.4.11(PPC,G4,32位)上运行下面的代码,并得到了输出:

$ p $ 现在:1225573977
格式化(12):011120082112
结束:0xBFFFF553(缓冲区:0xBFFFF547)
然后:year = 2008,month = 11,day = 1,hour = 21,分钟= 12
重新格式化(12):011120082112

我使用的代码是: p>

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

int main(void)
{
time_t now = time(0);
struct tm * tm = gmtime(& now);
char格式[] =%d%m%Y%H%M;
char buffer1 [64];
char buffer2 [64];
size_t f_len = strftime(buffer1,sizeof(buffer1),format,tm);
struct tm then;
char * end = strptime(buffer1,format,& then);
size_t p_len = strftime(buffer2,sizeof(buffer2),format,& then);

printf(Now:%ld\\\
,(long)now);
printf(Formatted(%lu):%s\\\
,(unsigned long)f_len,buffer1);
printf(End:0x%08lX(Buffer:0x%08lX)\\\
,(unsigned long)end,(unsigned long)buffer1);
printf(Then:year =%d,month =%d,day =%d,hour =%d,minute =%d \\\

then.tm_year + 1900,then。 tm_mon + 1,then.tm_mday,then.tm_hour,then.tm_min);
printf(Reformatted(%lu):%s\\\
,(unsigned long)p_len,buffer2);

return(0);



$ b $ p
$ b

根据我所看到的,strptime()在我使用的版本。我们可以讨论不存在的错误检查的优点,以及打印中C99 < inttypes.h> 符号的强制转换,但我认为代码是准确的。我用 gmtime()代替 localtime();我怀疑这是不是造成这个问题的一个因素。

也许你应该看一下PHP测试套件?
也许你应该把你相当复杂的表达式分成几块来检测错误发生在PHP的地方吗?

I am wrestling with a php 5.2.6 problem. An api we use returns dates in this format DDMMYYYYHHMM. Exactly that format, fixed length, no delimiters. However, in my experimentation, this format seems to break strptime, which returns a false (fail) when I feed it a date in this format. It can reproduced, at least on my system, with this example:

$format = "%d%m%Y%H%M"; echo print_r(strptime(strftime($format,1225405967),$format),true);

If I add any character between the date and the time, it works, even a space. So, this DOES work:

$format = "%d%m%Y %H%M"; echo print_r(strptime(strftime($format,1225405967),$format),true);

Am I missing something obvious?

edit: further to this and owing to the results indicated by the comments, this seems to be platform specific. I can reproduce it on the Macs running OSX Leopard in the office but the Linux boxes parse it fine. I assume it is a bug or idiosyncrasy of the strptime in the underlying C library in the *nix of OSX.

解决方案

If you think the problem is on MacOS X and in the C library, then you could produce a test case to demonstrate it. For example, I ran the code below on MacOS X 10.4.11 (PPC, G4, 32-bit), and got the output:

Now: 1225573977
Formatted (12): 011120082112
End: 0xBFFFF553 (Buffer: 0xBFFFF547)
Then: year = 2008, month = 11, day = 1, hour = 21, minute = 12
Reformatted (12): 011120082112

The code I used is:

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

int main(void)
{
    time_t now = time(0);
    struct tm *tm = gmtime(&now);
    char format[] = "%d%m%Y%H%M";
    char buffer1[64];
    char buffer2[64];
    size_t f_len = strftime(buffer1, sizeof(buffer1), format, tm);
    struct tm then;
    char *end = strptime(buffer1, format, &then);
    size_t p_len = strftime(buffer2, sizeof(buffer2), format, &then);

    printf("Now: %ld\n", (long)now);
    printf("Formatted (%lu): %s\n", (unsigned long)f_len, buffer1);
    printf("End: 0x%08lX (Buffer: 0x%08lX)\n", (unsigned long)end, (unsigned long)buffer1);
    printf("Then: year = %d, month = %d, day = %d, hour = %d, minute = %d\n",
            then.tm_year + 1900, then.tm_mon + 1, then.tm_mday, then.tm_hour, then.tm_min);
    printf("Reformatted (%lu): %s\n", (unsigned long)p_len, buffer2);

    return(0);
}

On the basis of what I see, there is no bug in strptime() in the version I'm using. We can debate about the merits of the non-existent error checking, and of the casts versus C99 <inttypes.h> notations in the printing, but I think the code is accurate enough. I used gmtime() instead of localtime(); I doubt if that was a factor in not reproducing the problem.

Maybe you should look at the PHP test suite? Maybe you should split your rather complex expression into pieces to detect where the error occurs in PHP?

这篇关于PHP的strptime格式错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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