PHP - 将字符串解析为过去的日期

PHP - Parsing String As Past Date

目前,我正在尝试将收到消息的日期解析为时间戳。我有月份和日期,但没有指定年份。该事件总是发生在最近的(人类)阅读时间。在大多数情况下这样做效果很好:

$time = strtotime("Jan 2 8:38pm");

那 return 是今年的日期,这是正确的。不幸的是,当我尝试这样做时遇到了问题,例如:

$time = strtotime("Dec 31 8:38pm");

那 return 是一个尚未发生的日期,并且在今年余下的时间里都不会发生。很明显,我的消息没有在以后发送。我需要它到 return 去年 12 月 31 日。

对于工作日,我有一个解决方案,方法是在工作日之前添加 'last',如下所示:

$time = strtotime("Last Saturday 8:38pm");

那总是 return 上周六的时间。然而,在这里尝试做同样的事情是行不通的:

$time = strtotime("Last Dec 31 8:38pm");

这 return 是错误的。我知道将日期减去 1 年,我可以这样做:

$time = strtotime("Dec 31 8:38pm -1 year");

这对 12 月 31 日非常有效。但是,1 月 2 日现在将失败:

$time = strtotime("Jan 2 8:38pm -1 year");

我想到的一个解决方案是,如果今天的日期已经过去,则从结果值中减去一年 (86400 * 365)。但是,如果我们超过了闰年的二月,这个结果就会失败。在那种情况下,我们最终会提前一天的时间。

到目前为止我想到的最好的解决方案是:

$time = strtotime($raw_time);
if ($time > time()) {
  $time = strtotime($raw_time." -1 year");
}

两次调用 strtotime 似乎有点浪费,我知道这可能不是一个非常有效的函数。这是最优雅的解决方案吗?

有人知道 strtotime 中的一个选项,它强制日期是过去的而不是未来的吗?

有没有我应该考虑的其他解析这些日期的方法?

效率对此很重要,因为我将用它解析很多日期,但我也想要简单易读的代码,以便以后可以理解。

您的方法很好,因为没有日期格式来获取您想要的内容。另一种方法可能是使用 DateTime class:

$datetime = new DateTime($raw_time);
if ($datetime > new DateTime()) {
    $datetime->modify('-1 year');
}

您可以测试这两种方法中哪一种更快。我的猜测是,这是一个 micro-optimization,不会产生太大影响。