strtotime结果毫无意义,php bug?

时间:2021-12-05 02:12:49

The following line:

以下行:

echo date('d', strtotime('First Saturday August 2015'));

prints 08, which doesn't seem to make any sense because the first occurrence of a day of the week can't be after the 7th.

打印08,这似乎没有任何意义,因为第一次出现的一周不能在7日之后。

Is it a php bug or a php bug or maybe even a php bug? I don't know...

它是一个php bug还是一个php bug,甚至可能是一个php bug?我不知道...

php version: 5.5.19

php版本:5.5.19

3 个解决方案

#1


44  

Update #1: explained below the big difference that a simple word like "of" makes, after I investigated a little in the PHP source code.

更新#1:在我在PHP源代码中稍微调查一下后,解释了一个像“of”这样的简单单词的巨大差异。

Update #2: There actually is a documentation page on PHP manual that explains the formats of dates accepted by strftime(). I just was not aware of it until now. Thanks @Outspaced for providing the link in their answer.

更新#2:实际上有一个关于PHP手册的文档页面,它解释了strftime()接受的日期格式。直到现在我才意识到这一点。感谢@Outspaced在他们的回答中提供链接。

For a quick and easy reading skip the section Update #1.

要快速轻松地阅读,请跳过更新#1部分。


The initial answer:

Indeed,

确实,

echo date('Y-m-d', strtotime('First Saturday August 2015'));

prints:

打印:

2015-08-08

But

echo date('Y-m-d', strtotime('First Saturday of August 2015'));

prints the correct date:

打印正确的日期:

2015-08-01

Since strtotime() tries to "understand" English, I guess you and it speak different dialects :-)

由于strtotime()试图“理解”英语,我想你和它说不同的方言:-)

Update #1:

After some reading in the PHP source code of function strtotime(), I think that it parses First Saturday August 2015 as First Saturday followed by August 2015.

在阅读了函数strtotime()的PHP源代码之后,我认为它将2015年8月的第一个星期六解析为第一个星期六,然后是2015年8月。

August 2015 is an absolute expression and because there is no indication about the day it produces 2015-08-01 (the 1st of August 2015) which is a reasonable guess (the only one possible, I think).

2015年8月是一个绝对的表达,因为没有迹象表明它生成2015-08-01(2015年8月1日)的那一天是一个合理的猜测(我认为唯一可能的)。

First Saturday is a relative expression. It is relative to an absolute mark provided in the string (August 2015) or as a second parameter of strtotime() and it "shifts" the timestamp of the absolute mark back or forward with some amount.

第一个星期六是相对表达。它相对于字符串中提供的绝对标记(2015年8月)或作为strtotime()的第二个参数,它以一定的量“向后或向前”移动绝对标记的时间戳。

Putting them together, strtotime() interprets First Saturday August 2015 as First Saturday counting since August 1, 2015 and that is, indeed, August 8, 2015.

将它们放在一起,strtotime()将2015年8月的第一个星期六解释为自2015年8月1日起的第一个星期六,即2015年8月8日。

On the other hand, First Saturday of August 2015 is parsed using a different rule. One of next, last, previous, this or any ordinal number from first to twelfth, followed by a weekday name (full or abbreviated) and followed by of is parsed as a weekday of the provided month (or the current month if none is provided in the string).

另一方面,使用不同的规则解析2015年8月的第一个星期六。从第一个到第十二个的下一个,最后一个,前一个,这个或任何序号,然后是工作日名称(完整或缩写),然后是of,将其解析为所提供月份的工作日(如果没有提供,则解析为当前月份)在字符串中)。

Update #2

After I found out that the format of the string accepted by strtotime() is actually explained in the PHP documentation, the explanation became more simple. Take a look at the second "Note:" box in the documentation page.

在我发现strtotime()接受的字符串格式在PHP文档中实际解释后,解释变得更加简单。请查看文档页面中的第二个“注意:”框。

First Saturday August 2015 is explained at item #4 in the note:

2015年8月的第一个星期六在说明中的第4项解释:

"ordinal dayname" does advance to another day.

“序数日名”确实进展到另一天。

First Saturday of August 2015 is explained at item #6 of the note:

2015年8月的第一个星期六在说明的第6项解释:

"ordinal dayname 'of'" does not advance to another day.

“ordinal dayname”的''不会提前到另一天。

The note ends with an entire block of explanation dedicated to the magical word "of".

该笔记以一整段解释结束,专门用于神奇的“of”字样。

#2


12  

You need an 'of':

你需要一个'of':

date('d/m/Y', strtotime('First Saturday of August 2015'))

see the manual: http://docs.php.net/manual/en/datetime.formats.relative.php

参见手册:http://docs.php.net/manual/en/datetime.formats.relative.php

#3


-2  

As stated, PHP didn't quite understand your choice of dialect. If you plan on accepting varied input from your users (not a bad idea) to express a date, I suggest doing some normalization of that user input yourself so that you can submit a predictable format to strtotime.

如上所述,PHP并不十分了解您对方言的选择。如果您计划接受来自用户的不同输入(不是一个坏主意)来表达日期,我建议您自己对该用户输入进行一些规范化,以便您可以向strtotime提交可预测的格式。

#1


44  

Update #1: explained below the big difference that a simple word like "of" makes, after I investigated a little in the PHP source code.

更新#1:在我在PHP源代码中稍微调查一下后,解释了一个像“of”这样的简单单词的巨大差异。

Update #2: There actually is a documentation page on PHP manual that explains the formats of dates accepted by strftime(). I just was not aware of it until now. Thanks @Outspaced for providing the link in their answer.

更新#2:实际上有一个关于PHP手册的文档页面,它解释了strftime()接受的日期格式。直到现在我才意识到这一点。感谢@Outspaced在他们的回答中提供链接。

For a quick and easy reading skip the section Update #1.

要快速轻松地阅读,请跳过更新#1部分。


The initial answer:

Indeed,

确实,

echo date('Y-m-d', strtotime('First Saturday August 2015'));

prints:

打印:

2015-08-08

But

echo date('Y-m-d', strtotime('First Saturday of August 2015'));

prints the correct date:

打印正确的日期:

2015-08-01

Since strtotime() tries to "understand" English, I guess you and it speak different dialects :-)

由于strtotime()试图“理解”英语,我想你和它说不同的方言:-)

Update #1:

After some reading in the PHP source code of function strtotime(), I think that it parses First Saturday August 2015 as First Saturday followed by August 2015.

在阅读了函数strtotime()的PHP源代码之后,我认为它将2015年8月的第一个星期六解析为第一个星期六,然后是2015年8月。

August 2015 is an absolute expression and because there is no indication about the day it produces 2015-08-01 (the 1st of August 2015) which is a reasonable guess (the only one possible, I think).

2015年8月是一个绝对的表达,因为没有迹象表明它生成2015-08-01(2015年8月1日)的那一天是一个合理的猜测(我认为唯一可能的)。

First Saturday is a relative expression. It is relative to an absolute mark provided in the string (August 2015) or as a second parameter of strtotime() and it "shifts" the timestamp of the absolute mark back or forward with some amount.

第一个星期六是相对表达。它相对于字符串中提供的绝对标记(2015年8月)或作为strtotime()的第二个参数,它以一定的量“向后或向前”移动绝对标记的时间戳。

Putting them together, strtotime() interprets First Saturday August 2015 as First Saturday counting since August 1, 2015 and that is, indeed, August 8, 2015.

将它们放在一起,strtotime()将2015年8月的第一个星期六解释为自2015年8月1日起的第一个星期六,即2015年8月8日。

On the other hand, First Saturday of August 2015 is parsed using a different rule. One of next, last, previous, this or any ordinal number from first to twelfth, followed by a weekday name (full or abbreviated) and followed by of is parsed as a weekday of the provided month (or the current month if none is provided in the string).

另一方面,使用不同的规则解析2015年8月的第一个星期六。从第一个到第十二个的下一个,最后一个,前一个,这个或任何序号,然后是工作日名称(完整或缩写),然后是of,将其解析为所提供月份的工作日(如果没有提供,则解析为当前月份)在字符串中)。

Update #2

After I found out that the format of the string accepted by strtotime() is actually explained in the PHP documentation, the explanation became more simple. Take a look at the second "Note:" box in the documentation page.

在我发现strtotime()接受的字符串格式在PHP文档中实际解释后,解释变得更加简单。请查看文档页面中的第二个“注意:”框。

First Saturday August 2015 is explained at item #4 in the note:

2015年8月的第一个星期六在说明中的第4项解释:

"ordinal dayname" does advance to another day.

“序数日名”确实进展到另一天。

First Saturday of August 2015 is explained at item #6 of the note:

2015年8月的第一个星期六在说明的第6项解释:

"ordinal dayname 'of'" does not advance to another day.

“ordinal dayname”的''不会提前到另一天。

The note ends with an entire block of explanation dedicated to the magical word "of".

该笔记以一整段解释结束,专门用于神奇的“of”字样。

#2


12  

You need an 'of':

你需要一个'of':

date('d/m/Y', strtotime('First Saturday of August 2015'))

see the manual: http://docs.php.net/manual/en/datetime.formats.relative.php

参见手册:http://docs.php.net/manual/en/datetime.formats.relative.php

#3


-2  

As stated, PHP didn't quite understand your choice of dialect. If you plan on accepting varied input from your users (not a bad idea) to express a date, I suggest doing some normalization of that user input yourself so that you can submit a predictable format to strtotime.

如上所述,PHP并不十分了解您对方言的选择。如果您计划接受来自用户的不同输入(不是一个坏主意)来表达日期,我建议您自己对该用户输入进行一些规范化,以便您可以向strtotime提交可预测的格式。