PHP: 一周从星期一开始,但在星期日使用“本周星期一”会得到下周的星期一。

36

以下是问题的概述:在星期天,strtotime('this week')返回下周的开始。

在PHP中,一周似乎从星期一开始。但是,在除了星期天以外的任何一天,这段代码

echo date('Y-m-d', strtotime('monday this week', strtotime('last sunday')));

输出本周星期一的日期,但实际上它似乎输出了上周的星期一。在这种情况下,PHP好像将周日和周一都视为一周的开始。现在是2012年12月10日星期一,date('Y-m-d', strtotime('sunday last week'))返回2012-12-09 - 昨天。

这是一个错误吗,还是我漏掉了什么?看起来如此明显的错误应该相当知名,但我找不到任何相关信息。获取一周的开始时间的唯一方式是对周日进行特殊处理吗?

$week_offset = (int) 'sunday' == date('l');
$week_start  = strtotime("-$week_offset monday"); // 1 or 0 Mondays ago

也许时区出了些问题?你可以尝试使用绑定到本地DateTimeZoneDateTime吗?另外,你是否更换了服务器的flux capacitor?它们会在一段时间后磨损。 :p - Charles
1
我认为 PHP 日期函数的一周第一天是星期日:_w | 一周中的星期几的数字表示 | 0(代表星期日)到6(代表星期六)_。 - Salman A
@Charles,我尝试这个方法,但是得到了相同的结果: $date = new DateTime(); $date->setTimezone(new DateTimeZone('America/Los_Angeles')); $date->setTimestamp(strtotime('last sunday')); echo $date->format('Y-m-d');此外,我已经检查过我的服务器,准电子流通速率应该是……无限制的。因此,我认为这不是问题所在。 - tvanc
你可能也想看看这个:http://stackoverflow.com/questions/5376484/issue-with-getting-week-starting-from-sunday。 - Peon
7
我已在此处发布了一个错误报告:https://bugs.php.net/bug.php?id=63740,请随意添加您的反馈意见。 - Salman A
显示剩余2条评论
10个回答

10
据我所知,这是一个bug。我找不到任何逻辑原因来解释为什么strtotime('this week');会返回一个未来日期。这是一个相当严重的bug。在我的特定情况下,我有一个排行榜,显示了从本周开始以来得分最高的用户。但是在星期天,它是空的,因为strtotime返回了一个未来日期的时间戳。我表示怀疑,因为我不知道如何可能没有人注意到这个问题,但我找不到其他关于这个bug的报告。
感谢大家的时间和帮助。

9
略微晚了一些,我遇到了同样的问题...你可以通过执行 strtotime('next Monday -1 week'); 来轻松解决这个问题。这将始终给出当前一周的星期一 ;) - Frederik Voordeckers
@FrederikVoordeckers 很好的想法!但是对我来说没有像那样工作,但这个可以:$this_date_start = new DateTime('next monday'); $this_date_start ->sub(new DateInterval('P7D')); - Hafenkranich
这个很好用 @FrederikVoordeckers。但是在星期天我必须使用 strtotime('sunday this week') - Martin

7

这个答案来得有些晚,但这是我一直苦苦挣扎的问题。到目前为止,我尝试过的每个解决方案都因为各种原因而失效了。以下是我最终使用并且有效的解决方案(虽然它可能看起来不太美观,但至少它可以正常工作)。

$thisMonday =  strtotime('next Monday -1 week', strtotime('this sunday'));

6
这里是获取本周星期一的方法:

echo date("Y-m-d", strtotime(date('o-\\WW')));

在一个星期一,返回上周星期一的日期。 echo date('Y-m-d', strtotime(date('o-\\WW'), strtotime('2013-02-18'))); 2013-02-18 是星期一。上述代码输出 2013-02-11,即上个星期一的日期。无论如何,它并没有解释为什么当我向 strtotime 提供“本周”时,PHP 应该返回未来的日期。 - tvanc
我刚刚使用了这个解决方案,strtotime(date('o-\WW')) 如果基准时间戳也是星期一,则返回相同的星期一。您使用的是哪个版本的PHP? - Capsule
1
@turibe,你的strtotime位置不对,应该是:echo date('Y-m-d', strtotime(date('o-\\WW', strtotime('2013-02-18')))); - glen-84

3

这不是最理想的方法,但这是我所采用的:

if(date('N') == 7) { 
    $date = date('Y-m-d',strtotime('monday last week'));
} else {
    $date = date('Y-m-d',strtotime('monday this week'));
}

0

根据Bryant的回答:

$first_week_date = date('d F Y', strtotime('next Monday -1 week', strtotime('this sunday')));
$last_week_date = date('d F Y', strtotime('next Monday -1 week + 6 days', strtotime('this sunday')));

0

这是为那些寻找适用于任何日期的友好解决方案的人而设计的。

function getWeekStart($week_start_day = "Monday") {
    $week_days = array("Sunday"=>0,"Monday"=>1,"Tuesday"=>2,"Wednesday"=>3,"Thursday"=>4,"Friday"=>5,"Saturday"=>6,);

    if(!isset($week_days[$week_start_day])) {
        return false;
    } else {
        $start_day = $week_days[$week_start_day];

        $today = date("w");
        $one_day = (60 * 60 * 24);

        if($today < $start_day) {
            $days_difference = 7 - ($start_day - $today);
        } else {
            $days_difference = ($today - $start_day);
        }

        $week_starts = strtotime(date("Y-m-d 00:00:00")) - ($one_day * $days_difference);

        return $week_starts;
    }
}

//Test: If today is Monday, it will return today's date
echo date("Y-m-d H:i:s", getWeekStart("Monday"));

0

我认为,与其试图

echo date('Y-m-d', strtotime('monday this week', strtotime('last sunday')));

你应该尝试一下

echo date('Y-m-d', strtotime('monday last week'));

如果我想获取上个星期一的日期,那么这个方法是可行的,但是我现在想要做的是获取最近一个星期一的日期,包括今天(如果今天是星期一)。date('Y-m-d', strtotime('this week'); 会返回星期一的日期,无论你在哪一天运行这段代码或者将 strtotime 的第二个参数设置为什么。 - tvanc
也就是说,我想要获取本周的开始。但是如果我在星期天尝试获取本周的开始,PHP会返回未来的一个日期:下个星期一。 - tvanc

0

试试这段代码

// set current date
$date = date("m/d/Y");
$ts = strtotime($date); // also $ts = time();

// find the year and the current week
$year = date('o', $ts);
$week = date('W', $ts);
// print week for the current date
$i = 1; // 1 denotes the first day of week

$ts = strtotime($year.'W'.$week.$i);
echo $day = date("l", $ts); // generate the name of day
echo "<br>";
echo $day = date("Y-m-d", $ts); // generate the date

您将获得当前一周的日期,无论您是星期一还是其他日子,您都将获得该星期一的日期。


我也在我的问题中展示了如何获得它,但出于半学术目的,我想知道这是否是一个错误,或者PHP行为存在有效原因。我无法理解那会是什么。如果这是个bug,我需要报告它。但似乎这么重要的bug还没有被报告过,这听起来很荒谬。 - tvanc
如前所述,这不是一个错误。如果您选择使用“单词类型”短语,PHP会将星期一视为一周的开始。如果您希望它以星期日作为一周的开始,则需要进行一些解决方法。 - Peon
3
@DainisAbols 我知道PHP认为周一是一周的开始。我不想把周日作为一周的开始。 在周日,strtotime('this week')返回下一周。这似乎是一个错误。 - tvanc

0

如果你想要最近的星期一:

function mostRecentMonday(){
  if(date("w") == 1){
   return strtotime("midnight today");
  } else {
   return strtotime("last monday");
  }
}

很容易修改以使用DateTime,或者甚至指定一个不同的日期作为基础。


1
为了保持一致性,您应该使用strtotime('midnight today')而不是time(),因为last monday返回那天的午夜。 - antriver
@antriver同意了。我更新了我的评论以反映你的建议。原始例子没有处理时间组件(只有Y-m-d),所以它并不重要,但保持一致总是好的。 - chasepeeler

0
  I think the only problem with your coding is TimeZone.

解决方案:
设置自己的时区。以下是我的时区示例:

示例

   date_default_timezone_set('Asia/Kolkata');


   Set the above line before calling any time function.

祝您有美好的一天。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接