PHP获取时间戳慢了8个小时

回复列表(30|隐藏机器人聊天)
  • @Ta / 2022-09-07 / /

    @511,如果你设置了date_default_timezone_set('PRC');
    直接拿数据库的时间戳出来date解析成时间格式将得到正确的结果,因为date会自动添加时区偏移,不需要你手动添加。

  • @Ta / 2022-09-07 / /
    date_default_timezone_set('PRC'); // 设置了时区
    $time = time(); // 这里不添加时区偏移
    echo date('Y-m-d H:i:s', $time); // 这里将自动添加时区偏移
    
  • 511
    @Ta / 2022-09-07 / /
    @老虎会游泳
    echo gmdate('Y-m-d H:i:s', strtotime(date("Y-m-d H:i:s")));
    比如是这样呢
  • @Ta / 2022-09-07 / /

    @511,你是不熟悉 php 函数吗?可以翻翻PHP官方文档(中文) - gmdate

    date() 函数完全一样,只除了返回的时间是格林威治标准时(GMT)

  • @Ta / 2022-09-07 / /

    @511,我虽然不熟悉 php,即使不看文档,只要自己动动手,也能猜出意思来了:

    echo date("Y-m-d H:i:s", 10) . "\n";
    /* 输出:1970-01-01 08:00:10
     * 猜测:date() 会将 UNIX时间戳 10 转换为 『本地时区』的时间字符串
     */
    
    echo strtotime(date("Y-m-d H:i:s", 10)) . "\n";
    /* 输出:10
     * 猜测:strtotime() 会将 『本地时区』的时间字符串 转换为 『世界时』的时间戳
     */
    
    echo gmdate("Y-m-d H:i:s", 10) . "\n";
    /* 输出:1970-01-01 00:00:10
     * 猜测:gmdate() 会将 UNIX时间戳 10 转换为 『世界时』的时间字符串
     */
    
  • @Ta / 2022-09-08 / /

    @511,你故意使用gmdate,当然不会得到正确的结果。只要你没有这种故意,结果就会是正确的,你也不需要对unix时间戳进行偏移。

    date_default_timezone_set('PRC');
    echo date('Y-m-d H:i:s', strtotime(date("Y-m-d H:i:s")));
    
  • @Ta / 2022-09-08 / /
    date_default_timezone_set('PRC');
    echo gmdate('Y-m-d H:i:s', strtotime(date("Y-m-d H:i:s")));
    

    以上代码当然会得到一个协调世界时输出,因为是你自己想要一个协调世界时输出——gm就是这个意思。

    你不能一边说“给我输出协调世界时”(在date前加gm),一遍喊“结果怎么比北京时间慢了8小时?”

    当然是因为你想要协调世界时(date前加了gm),而协调世界时就是比北京时间慢8小时。

  • @Ta / 2022-09-08 / /

    所以,为什么PHP获取时间戳慢了8个小时?

    因为你用错了函数。

    如果你想用date_default_timezone_set('PRC');设置时区,你就只能使用

    • date
    • mktime
    • strftime

    而不能使用

    • gmdate
    • gmmktime
    • gmstrftime

    因为gm表示“给我忽略时区,我要的是协调世界时”。

    还有,标题中的时间戳慢了8个小时表述也不正确,因为时间戳是协调世界时的整数表示,它可不会因为时区改变而变快变慢,只有“时间字符串”(年月日时分秒)会慢。

    所以,你的问题应该表述为“为什么PHP把时间戳转换为时间字符串时慢了8个小时?”

    答:因为你加了gm,所以如你所愿,输出了协调世界时。

    • date:将unix时间戳(协调世界时的整数表示)转换为本地时间字符串(如果有date_default_timezone_set('PRC');就是北京时间)

    • gmdate:将unix时间戳(协调世界时的整数表示)转换为协调世界时时间字符串(不受date_default_timezone_set('PRC');的影响)

  • @Ta / 2022-09-08 / /

    当然,如果你喜欢错上加错,你倒是可以使用这种解决方案:

    date_default_timezone_set('PRC');
    echo gmdate('Y-m-d H:i:s', strtotime(date("Y-m-d H:i:s").' UTC'));
    

    Screenshot_20220908_044842.jpg(116.25 KB)

    date("Y-m-d H:i:s")输出的其实是北京时间,但通过在后面附加UTC,可以让strtotime把它视为协调世界时,于是它返回一个偏移8小时后的unix时间戳(unix时间戳变快8小时)。

    因为unix时间戳变快了8小时,所以再交给gmdate处理时,输出的协调世界时自然也变快了8小时。

    虽然结果是正确的,但这显然不是gmdate的正确用法。

    如果你不需要协调世界时输出,就不应该在date前加gm

  • 511
    @Ta / 2022-09-08 / /
    @老虎会游泳@无名啊,原来如此,一直用错办法了,用date就OK了哈哈哈,感谢解答
  • @Ta / 2022-09-08 / /

    @511@老虎会游泳
    总结起来就是一句话嘛,time()无视时区,date受时区影响,我之前也不清楚,在数据库里踩了坑
    https://hu60.cn/q.php/bbs.topic.103494.html
    https://hu60.cn/q.php/bbs.topic.103571.html

添加新回复
回复需要登录