for ($i=1; $i<=12; $i++) {
$monthNum = $i;
$monthName = date('F', mktime(0, 0, 0, $monthNum, 10));
$date_established = strtotime($monthName);
$date_established = strtotime('first day of this month', $date_established);
$date_established = date('Y-m-d', $date_established);
$date_established_end = date("Y-m-t", strtotime($date_established));
echo $i .'::'. $monthName . '::' . $date_established . '::' . $date_established_end . '<br>';
}
到目前为止,它产生:
1::January::2016-01-01::2016-01-31
2::February::2016-02-01::2016-02-28
3::march::2016-03-01::2016-03-31
4::April::2016-04-01::2016-04-30
5::May::2016-05-01::2016-05-31
6::June::2016-06-01::2016-06-30
7::July::2016-07-01::2016-07-31
8::August::2016-08-01::2016-08-31
9::September::2016-09-01::2016-09-30
10::October::2016-10-01::2016-10-31
11::November::2016-11-01::2016-11-30
12::December::2016-12-01::2016-12-31
但是今天(2016年12月31日),所有这些都搞砸了:
1::January::2016-01-01::2016-01-31
2::February::2016-03-01::2016-03-31
3::march::2016-03-01::2016-03-31 << duplicate
4::April::2016-05-01::2016-05-31
5::May::2016-05-01::2016-05-31 << duplicate
6::June::2016-07-01::2016-07-31
7::July::2016-07-01::2016-07-31 << duplicate
8::August::2016-08-01::2016-08-31
9::September::2016-10-01::2016-10-31
10::October::2016-10-01::2016-10-31 << duplicate
11::November::2016-12-01::2016-12-31
12::December::2016-12-01::2016-12-31 << duplicate
2016年12月31日有什么问题?为什么我的代码搞砸了?谢谢.
解决方法:
您的代码失败了:
$february = strtotime('February');
echo date(DATE_ISO8601, $february);
今天,2016年12月30日输出:
2016-03-01T00:00:00+0000
嗯……为什么PHP说“二月”是“2016-03-01”?好吧,它与PHP如何填补缺失信息的空白有关:在没有明确给定绝对时间值的情况下,PHP使用当前日期和时间的值.
因此,由于它是12月30日东部时间13:29,以下是语义等价的:
strtotime('February'); // you asked for
strtotime('February 30, 2016 13:29:47 EST'); // PHP interprets as
// ^^^^^^^^^^^^^^^^^^^^^ filled in from current time
显然,后者,解释日期是假的. PHP(通过底层库,实际上)使用2月30日= 2月29日1天= 3月1日的逻辑来改变解释日期.(更糟糕的是,在像2017年的非闰年,PHP将计算2月30日= 2月28日2天= 3月2日,输出为“2017-03-02T00:00:00 0000”!)
因此,在您要求PHP进行日期转换时,在这些情况下,您需要做的是明确的.这意味着而不是要求strtotime(‘二月’);你要求:
$year = date('Y');
$date_established = strtotime("$monthName 1, $year");
(或等效.重点是:不要让PHP用当前日期的值填充缺少的信息.)
另外:这些错误特别难以追踪,因为当月的当天小于所要求的月份的天数时,代码“有效”.根据我的经验,除非你绝对需要,否则最好避免使用strtotime,当你绝对需要时,你尽可能多地提供明确的信息.