【问题标题】:strtotime php function not behaving as expectedstrtotime php 函数未按预期运行
【发布时间】:2011-10-31 19:50:48
【问题描述】:

我正在尝试编写一些 php 来确定给定工作日下一次出现的日期(Y-m-d 格式)。

date('Y-m-d', strtotime('next monday'));

回来了

2011-08-29

而不是

2011-08-22

在我的服务器上。不知道为什么。我的服务器是亚马逊美国东海岸数据中心的一个 EC2 实例,目前是 2011-08-21 9:40:00。

编辑 1 同样date('Y-m-d', strtotime('next sunday')); 返回2011-08-28 而不是今天。我在http://writecodeonline.com/php/ 上试用了这段代码……开始认为测试仪不准确。

【问题讨论】:

  • 我会更多地查看您服务器的时区设置:“此函数将使用 TZ 环境变量(如果可用)来计算时间戳。从 PHP 5.1.0 开始,有更简单的方法来定义在所有日期/时间函数中使用的时区。该过程在 date_default_timezone_get() 函数页面中进行了说明。 php.net/manual/en/function.strtotime.php
  • 我还建议先检查时区。 date('Y-m-d', strtotime('today')); 的含义是什么?

标签: php date strtotime epoch


【解决方案1】:

仅仅因为您的服务器设置为某个时区并不一定意味着 PHP 将在同一时区运行。欧洲已经是 2011 年 8 月 22 日星期一,其中还包括 UTC。如果您的 PHP 在这个时区运行,“下周一”是 8 月 29 日。

您应该在 PHP 中仔细检查您的时区设置。您可以运行date_default_timezone_get() 来检查您的安装使用的设置,或者尝试通过date_default_timezone_set("America/New_York"); 强制您的PHP 脚本使用您期望的时区,看看您是否得到了您期望的结果。

我刚刚测试了这个:

date_default_timezone_set("America/New York");
echo date('Y-m-d', strtotime('next monday')); // prints 2011-08-22
date_default_timezone_set("UTC");
echo date('Y-m-d', strtotime('next monday')); // prints 2011-08-29

【讨论】:

  • 我试过 date_default_timezone_get() 并且你是正确的,它设置为 UTC。我现在要尝试更改它。
  • +1,很好的一点,很多人都没有想到。
【解决方案2】:

我认为这是预期的行为,因为星期一还没有过去,strtotime 将其视为下星期一。

【讨论】:

    【解决方案3】:

    您使用的是哪个版本的 PHP?在 PHP 的某些版本中,strtotime 确实存在错误行为。

    我在strtotime手册页中找到了:

    5.0.2 在 PHP 5 到 5.0.2 中,“现在”和其他相对时间从今天的午夜开始计算错误。这与从当前时间正确计算的其他版本不同。

    5.0.0 开始允许微秒,但它们被忽略。

    4.4.0 在 4.4.0 之前的 PHP 版本中,“next”被错误地计算为 +2。一个典型的解决方案是使用“+1”。

    您描述的行为表明您的版本介于 5.05.0.2 之间。

    我建议你检查一下今天和计算出来的“下周一”之间的差是否大于 7 天。如果是,则减去 7 天,您就得到了实际日期。

    尝试使用该代码:

    $days = ((strtotime('next monday') - time()) / 60 / 60 / 24);
    if ($days >= 8) {
      $days -= 7;
    }
    

    我知道有date_diff 功能,但是如果您的PHP 版本像我想的那么低,那么您就无法使用它(抱歉,只有5.3.0 和更高版本)。

    【讨论】:

    • 现在还有人为 5.0.2 提供托管服务吗?
    • 可能自己的服务器,很久没升级了?
    • 确实如此。 FWIW,我并不是要暗示你错了。我只是对有人仍在使用 5.0 的想法感到惊讶。我很生气我的主机还没有推出 5.3。 :)
    【解决方案4】:

    “下一个”,当与工作日一起使用时,通常表示下一个最接近的日期之后的第一个。例如,如果今天是 21 日星期日,那么“下一个”星期一不是明天 22 日而是下一个星期一 29 日。

    我知道这不一定是直观的,也不是普遍认可的,但我相信这就是 strtotime() 解释“下一个”的方式。

    编辑:我已经通过自己的测试确认我是不正确的,并且“下一个”应该返回即将到来的第一个工作日(在上面的示例中为 22 日)。我将在此处保留此答案未经编辑,因为下面的评论可能对其他人有帮助。

    【讨论】:

    • 不幸的是,没有。为避免混淆,PHP 将“下周一”(表示从现在开始的下一个周一)与“下周的周一”(即下一个周一之后的周一)分开。因此,如果今天是 8 月 21 日,则“下周一”将返回 8 月 22 日,“上周六”将返回 8 月 20 日,“下周星期一”将返回 8 月 29 日。
    猜你喜欢
    • 1970-01-01
    • 2020-06-02
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多