当使用strtotime的序数值时,我有时会得到意想不到的结果。例如,为什么
date("M j", strtotime("second Tuesday February 2011"))
导致“2月15日”(实际上是2011年的第三周二?
答案 0 :(得分:5)
你错过了'of'。
$ php -r'回音日期(“M j”,strtotime(“2011年2月2日星期二”));'
2月15日$ php -r'回音日期(“M j”,strtotime(“2011年2月第二个星期二”));'
2月8日
PHP版本:
$ php -v
PHP 5.3.3(cli)(建于2010年8月22日19:41:55)
版权所有(c)1997-2010 PHP小组
Zend Engine v2.3.0,版权所有(c)1998-2010 Zend Technologies
documentation告诉你原因:
同时观察“序数”中的“of” 空间日名空间''和''最后' 空间日名空间'''确实如此 特别的东西。
- 它将日期设置为1。
- “ordinal dayname”的“不” 前进到另一天。 (例: “2008年7月的第一个星期二”意味着 “2008-07-01”)。
- “ordinal dayname”确实如此 前进到另一天。 (例: “2008年7月的第一个星期二”意味着 “2008-07-08”,另见第4点 上面的列表)。
答案 1 :(得分:2)
manual for strtotime()告诉您的搜索内容
在5.2.7之前的PHP 5中,请求a 在给定的工作日发生 那个工作日的一个月 这个月的第一天会 错误地添加一周到 返回时间戳。这一直是 在5.2.7及更高版本中更正。
简而言之,这是您正在使用的版本中的一个错误。
如果您正在寻找某种适用的修补程序,则删除序数值似乎有效(就好像第一个/第二个/第三个指示整周)
echo date("M j", strtotime("Tuesday February 2011")), '<br>';
echo date("M j", strtotime("first Tuesday February 2011")), '<br>';
echo date("M j", strtotime("second Tuesday February 2011")), '<br>';
echo date("M j", strtotime("third Tuesday February 2011")), '<br>';
答案 2 :(得分:0)
似乎依靠strtotime处理序数日期计算是不安全的 - 至少在PHP的版本中&lt; 5.3。 (我已经使用5.2.9和5.2.11进行了测试,尽管在线文档中声称该错误已在5.2.7中得到修复,但它们都无法工作。)
根据建议添加“of”显然只适用于php 5.3+并且完全删除序号会返回“第一次”发生,但其他序数将会休息7天。
PHP 5.2的最佳解决方案似乎是这样的:
$recurrOrdinal = "last";
$dayOfWeek = "Thursday";
$monthYear = "March 2011";
echo ordinalDate($recurrOrdinal, $dayOfWeek, $monthYear);
function ordinalDate($recurrOrdinal, $dayOfWeek, $monthYear) {
$firstDate = date("j", strtotime($dayOfWeek . " " . $monthYear) );
if ($recurrOrdinal == "first")
$computed = $firstDate;
elseif ($recurrOrdinal == "second")
$computed = $firstDate + 7;
elseif ($recurrOrdinal == "third")
$computed = $firstDate + 14;
elseif ($recurrOrdinal == "fourth")
$computed = $firstDate + 21;
elseif ($recurrOrdinal == "last") {
if ( ($firstDate + 28) <= date("t", strtotime($monthYear)) )
$computed = $firstDate + 28;
else
$computed = $firstDate + 21;
}
return date("Y-m-d", strtotime($computed . " " . $monthYear) );
}