【问题标题】:PHP strptime format bug?PHP strptime 格式错误?
【发布时间】:2008-10-31 17:10:38
【问题描述】:

我正在努力解决 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);

我是否遗漏了一些明显的东西?

编辑:除此之外,由于 cmets 指示的结果,这似乎是特定于平台的。我可以在办公室运行 OSX Leopard 的 Mac 上重现它,但 Linux 机器可以很好地解析它。我认为这是 OSX *nix 中底层 C 库中 strptime 的错误或特性。

【问题讨论】:

  • 您使用的是什么平台?我在 PHP 5.2.6 (cli) Linux Kernel 2.6.9-55 上尝试了您的示例,并且有两个看起来完全相同的数组输出。
  • 我的开发平台是 OSX Leopard 和 Apache2。有趣的结果,感谢您的回复。
  • 这一直看起来更特定于平台。我可以让它在另一个运行另一个 Linux 发行版的服务器上工作(两个例子)。我将继续在 Mac OSX 附带的 C 库中的 strptime 中搜索已知错误。看来这就是我的问题所在。
  • 祝你好运!抱歉,我没有任何 Mac 平台可供测试。
  • 我遇到了你在 Leopard 上使用股票 PHP 描述的问题。我在同一个盒子上的 MAMP 安装工作正常。

标签: php formatting strptime


【解决方案1】:

此功能取决于区域设置。您是否尝试过设置不同的语言环境? (见setlocale()

【讨论】:

    【解决方案2】:

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

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

    我使用的代码是:

    #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);
    }
    

    根据我所看到的,我正在使用的版本中 strptime() 没有错误。我们可以讨论不存在的错误检查的优点,以及在打印中强制转换与 C99 &lt;inttypes.h&gt; 符号的优点,但我认为代码足够准确。我用gmtime() 代替localtime();我怀疑这是否是导致问题不重现的一个因素。

    也许你应该看看 PHP 测试套件? 也许您应该将您相当复杂的表达式拆分为多个部分,以检测 PHP 中错误发生的位置?

    【讨论】:

      【解决方案3】:

      没有什么明显的,因为这两个版本在 PHP 5.2.0 中都可以正常工作。不过,我现在不能轻易检查 5.2.6。那得等我回家了。

      【讨论】:

      • 感谢您的回复。它似乎是特定于平台的。我的 OSX Leopard 开发平台和底层 C 库中的 strptime 似乎是罪魁祸首。我也无法在 Linux 机器上重现它,但办公室中的两台 Mac 都显示相同的行为。
      【解决方案4】:

      这很可能仅适用于 Mac,因为它甚至还没有在 Windows 上实现(尽管我已经通过了这个建议)。

      5.2.6
      Fatal error: Call to undefined function strptime() in F:\htdocs\strptime.php on line 5
      

      我会继续在bugs.php.net 提交错误。

      【讨论】:

        【解决方案5】:

        我确认:

            $p = strptime("09.02.2002", "%d.%m.%Y");
            var_dump($p);
        

        输出:

        数组(9){ [“tm_sec”]=> 整数(0) [“tm_min”]=> 整数(0) ["tm_hour"]=> 整数(0) ["tm_mday"]=> 整数(9) [“tm_mon”]=> 整数(1) ["tm_year"]=> 整数(102) ["tm_wday"]=> 整数(0) ["tm_yday"]=> 整数(0) [“未解析”]=> 字符串(0)“” }

        OS X Leopard,PHP 5.3.2

        【讨论】:

          猜你喜欢
          • 2015-11-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-11-29
          • 2017-06-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多