使用 strtotime 获取一个月中的第一个工作日

发布于 2024-10-06 06:07:04 字数 1012 浏览 4 评论 0原文

我试图使用 strtotime 计算出给定月份的第一个星期三,但是每当第一个星期三恰好是 1 号时,“第一个星期三”参数就会失败。

有关此问题的更一般说明,请参阅以下代码和结果:

$mon = strtotime("December 2010 first monday");
$tue = strtotime("December 2010 first tuesday");
$wed = strtotime("December 2010 first wednesday");
$thu = strtotime("December 2010 first thursday");
$fri = strtotime("December 2010 first friday");
$sat = strtotime("December 2010 first saturday");
$sun = strtotime("December 2010 first sunday");

echo strftime("%m/%d/%y", $mon) . "<br>";
echo strftime("%m/%d/%y", $tue) . "<br>";
echo strftime("%m/%d/%y", $wed) . "<br>";
echo strftime("%m/%d/%y", $thu) . "<br>";
echo strftime("%m/%d/%y", $fri) . "<br>";
echo strftime("%m/%d/%y", $sat) . "<br>";
echo strftime("%m/%d/%y", $sun) . "<br>";

结果:

12/06/10
12/07/10
12/08/10
12/02/10
12/03/10
12/04/10
12/05/10

注意到什么了吗?一周中的某一天不应该与该月的第一天一致吗?但它永远不会返回,而是总是返回当天的第二个实例(即 8 号)。

有人对此有解释吗?

I'm trying to figure out the first wednesday of a given month using strtotime, but the "first wednesday" argument fails whenever the first wednesday happens to fall on the 1st.

For a more general illustration of this problem, see the following code and result:

$mon = strtotime("December 2010 first monday");
$tue = strtotime("December 2010 first tuesday");
$wed = strtotime("December 2010 first wednesday");
$thu = strtotime("December 2010 first thursday");
$fri = strtotime("December 2010 first friday");
$sat = strtotime("December 2010 first saturday");
$sun = strtotime("December 2010 first sunday");

echo strftime("%m/%d/%y", $mon) . "<br>";
echo strftime("%m/%d/%y", $tue) . "<br>";
echo strftime("%m/%d/%y", $wed) . "<br>";
echo strftime("%m/%d/%y", $thu) . "<br>";
echo strftime("%m/%d/%y", $fri) . "<br>";
echo strftime("%m/%d/%y", $sat) . "<br>";
echo strftime("%m/%d/%y", $sun) . "<br>";

Results in:

12/06/10
12/07/10
12/08/10
12/02/10
12/03/10
12/04/10
12/05/10

Notice something? Shouldn't one day of the week coincide with the 1st of the month? But it never does, and instead the second instance of the day, on the 8th, is always returned.

Anyone have an explanation for this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

晒暮凉 2024-10-13 06:07:04

根据所提供的答案,需要了解 php 5.2 和 php 5.3 之间相对日期格式的差异。

测试:

$date1 = strtotime("first wednesday of 2010-12");
$date2 = strtotime("first wednesday 2010-12");
$date3 = strtotime("wednesday 2010-12");

5.2 结果:

1969-12-31
2010-12-08
2010-12-01

5.3 结果:

2010-12-01
2010-12-08
2010-12-01

因此,只有第三种方法在 PHP 5 版本中返回正确的结果。

Building off the answers provided, one needs to be aware of differences in relative date formatting between php 5.2 and php 5.3.

TEST:

$date1 = strtotime("first wednesday of 2010-12");
$date2 = strtotime("first wednesday 2010-12");
$date3 = strtotime("wednesday 2010-12");

5.2 Results:

1969-12-31
2010-12-08
2010-12-01

5.3 Results:

2010-12-01
2010-12-08
2010-12-01

Therefore only the third method returns correct results across PHP 5 versions.

痕至 2024-10-13 06:07:04

我没有任何解释,因为我也很眼花缭乱,但我设法找出如何通过省略“第一个”来获得正确的日期,如下所示:

$ php -r 'echo date("m/d/y", strtotime("December 2010 Wednesday"));'
12/01/10

$ php -r 'echo date("m/d/y", strtotime("December 2010 Thursday"));'
12/02/10

$ php -r 'echo date("m/d/y", strtotime("December 2010 Friday"));'
12/03/10

$ php -r 'echo date("m/d/y", strtotime("December 2010 Saturday"));'
12/04/10

$ php -r 'echo date("m/d/y", strtotime("December 2010 Sunday"));'
12/05/10

$ php -r 'echo date("m/d/y", strtotime("December 2010 Monday"));'
12/06/10

$ php -r 'echo date("m/d/y", strtotime("December 2010 Tuesday"));'
12/07/10

I don't have any explanation as I'm also dazzled, but I managed to find out how you get the correct date by omitting the "first", like so:

$ php -r 'echo date("m/d/y", strtotime("December 2010 Wednesday"));'
12/01/10

$ php -r 'echo date("m/d/y", strtotime("December 2010 Thursday"));'
12/02/10

$ php -r 'echo date("m/d/y", strtotime("December 2010 Friday"));'
12/03/10

$ php -r 'echo date("m/d/y", strtotime("December 2010 Saturday"));'
12/04/10

$ php -r 'echo date("m/d/y", strtotime("December 2010 Sunday"));'
12/05/10

$ php -r 'echo date("m/d/y", strtotime("December 2010 Monday"));'
12/06/10

$ php -r 'echo date("m/d/y", strtotime("December 2010 Tuesday"));'
12/07/10
听闻余生 2024-10-13 06:07:04

只是你的格式不正确。您需要包含 of

echo strftime("%m/%d/%y", strtotime("first Monday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Tuesday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Wednesday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Thursday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Friday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Saturday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Sunday of December 2010"));

打印:

12/06/10
12/07/10
12/01/10
12/02/10
12/03/10
12/04/10
12/05/10

接受的解决方案有效,但如果您想查找第二个工作日,您会遇到问题:

echo strftime("%m/%d/%y", strtotime("December 2010 second Wednesday"));

打印:

12/15/10

文档中给出了一些示例:

http://www.php.net/manual/en/datetime.formats.relative.php< /a>

上述文档中的第二块注释解释了 of 如何影响日期计算过程:

还要注意“序数”中的“of”
空间日名空间 'of' " 和 "'last'
空间日名空间 'of' " 确实
一些特别的东西。

  1. 它将月份中的某一天设置为 1。
  2. “ordinal dayname 'of' ”不会前进到另一天。 (例子:
    “2008 年 7 月第一个星期二”意味着
    “2008-07-01”)。
  3. “ordinal dayname”确实前进到另一天。 (例如:“首先
    2008 年 7 月星期二”表示“2008-07-08”,
    另请参见上面列表中的第 4 点)。
  4. "'last' dayname 'of' " 取当月的最后一个日期名称。
    (示例:“2008 年 7 月最后一个星期三”
    意思是“2008-07-30”)
  5. “'last' dayname”采用当天的最后一个日期名称。
    (例如:“2008 年 7 月最后一个星期三”的意思是
    “2008-06-25”; 《2008年7月》第一集
    当前日期为“2008-07-01”并且
    然后“最后一个星期三”移动到上一个
    星期三,即“2008-06-25”)。

It's just your formatting that is incorrect. You need to include of:

echo strftime("%m/%d/%y", strtotime("first Monday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Tuesday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Wednesday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Thursday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Friday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Saturday of December 2010"));
echo strftime("%m/%d/%y", strtotime("first Sunday of December 2010"));

Prints:

12/06/10
12/07/10
12/01/10
12/02/10
12/03/10
12/04/10
12/05/10

The accepted solution works, but you would encounter problems if you wanted to find the second weekday:

echo strftime("%m/%d/%y", strtotime("December 2010 second Wednesday"));

Prints:

12/15/10

There are some examples given in the docs:

http://www.php.net/manual/en/datetime.formats.relative.php

The second block of notes in the above documentation explains how of affects the date calculation process:

Also observe that the "of" in "ordinal
space dayname space 'of' " and "'last'
space dayname space 'of' " does
something special.

  1. It sets the day-of-month to 1.
  2. "ordinal dayname 'of' " does not advance to another day. (Example:
    "first tuesday of july 2008" means
    "2008-07-01").
  3. "ordinal dayname " does advance to another day. (Example: "first
    tuesday july 2008" means "2008-07-08",
    see also point 4 in the list above).
  4. "'last' dayname 'of' " takes the last dayname of the current month.
    (Example: "last wed of july 2008"
    means "2008-07-30")
  5. "'last' dayname" takes the last dayname from the current day.
    (Example: "last wed july 2008" means
    "2008-06-25"; "july 2008" first sets
    the current date to "2008-07-01" and
    then "last wed" moves to the previous
    Wednesday which is "2008-06-25").
汹涌人海 2024-10-13 06:07:04

我在 PHP 手册中找到了这个注释。

“在 5.2.7 之前的 PHP 5 中,请求某个月份中某个给定工作日的给定出现(该工作日是该月的第一天)会错误地在返回的时间戳中添加一周。这一问题已在 5.2.7 和以后的版本。”

I found this note in the PHP manual.

"In PHP 5 prior to 5.2.7, requesting a given occurrence of a given weekday in a month where that weekday was the first day of the month would incorrectly add one week to the returned timestamp. This has been corrected in 5.2.7 and later versions."

可可 2024-10-13 06:07:04

PHP 5.5.11

$firstWeekdayOfMonth = new DateTime('first weekday 0 jun 2016');

我不知道为什么,但是零类型强制 strtotime 解析器在月初启动考虑到第一天。

PHP 5.5.11

$firstWeekdayOfMonth = new DateTime('first weekday 0 jun 2016');

I don't know why, but the zero kind of force the strtotime parser to start at the beginning of the month considering the first day.

壹場煙雨 2024-10-13 06:07:04

我相信这是您放置值的顺序。
当您写“2010 年 12 月”时,已经到了 12/01/2010。当添加“首先
{day}”,函数适用于 2010 年 12 月 1 日之后的第一天。我认为,如果您声明“第一个 {day}”值,然后声明“2010 年 12 月”,它应该可以正常工作。

I believe it's the order in which you are placing values.
When you write "December 2010", it already is going to 12/01/2010. When adding "first
{day}", function goes for that very first day, after the 12/01/2010. I think if you declare the "first {day}" value and then "december 2010" it should work fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文