【问题标题】:Get Start and End Days for a Given Week in PHP在 PHP 中获取给定一周的开始和结束天数
【发布时间】:2009-05-29 00:44:15
【问题描述】:

我正在尝试使用星期日作为开始日期和参考日期(例如 $date)来获取周范围,但我似乎无法弄清楚。

例如,如果我的 $date 是 2009-05-01,我会得到 2009-04-26 和 2009-05-02。 2009-05-10 将产生 2009-05-10 和 2009-05-16。我当前的代码看起来像这样(我不记得我是从哪里取出它的,因为我忘记在我的 cmets 中写下 url):

function x_week_range(&$start_date, &$end_date, $date)
{
    $start_date = '';
    $end_date = '';
    $week = date('W', strtotime($date));
    $week = $week;

    $start_date = $date;

    $i = 0;
    while(date('W', strtotime("-$i day")) >= $week) {
        $start_date = date('Y-m-d', strtotime("-$i day"));
        $i++;
    }

    list($yr, $mo, $da) = explode('-', $start_date);

    $end_date = date('Y-m-d', mktime(0, 0, 0, $mo, $da + 6, $yr));
}

我意识到它所做的只是在当前日期上增加 7 天。你会怎么做呢?

【问题讨论】:

    标签: php datetime


    【解决方案1】:

    我会利用 PHP 的 strtotime 的优势:

    function x_week_range(&$start_date, &$end_date, $date) {
        $ts = strtotime($date);
        $start = (date('w', $ts) == 0) ? $ts : strtotime('last sunday', $ts);
        $start_date = date('Y-m-d', $start);
        $end_date = date('Y-m-d', strtotime('next saturday', $start));
    }
    

    根据您提供的数据进行了测试,并且有效。不过,我并不特别喜欢你正在进行的整个参考。如果这是我的功能,我会是这样的:

    function x_week_range($date) {
        $ts = strtotime($date);
        $start = (date('w', $ts) == 0) ? $ts : strtotime('last sunday', $ts);
        return array(date('Y-m-d', $start),
                     date('Y-m-d', strtotime('next saturday', $start)));
    }
    

    然后这样称呼它:

    list($start_date, $end_date) = x_week_range('2009-05-10');
    

    我不喜欢为这样的事情做数学。日期很棘手,我更喜欢让 PHP 弄清楚。

    【讨论】:

    • 我使用以下格式获取最后一个星期天的日期:date('Y-m-d',strtotime('last sunday'))
    • 试试 PHP5 DateTime 类!
    • @John M,请参阅下面的评论,如果今天是星期天并且您想要周,那么“上个星期日”可能会有问题。
    • 如果你想从周一到周日开始一周,那么代码的一些变化..function x_week_range($date) { $ts = strtotime($date); $start = (date('w', $ts) == 0) ? $ts : strtotime('本周星期一', $ts);返回日期('Y-m-d',$start)。' to '.date('Y-m-d', strtotime('本周日', $start)); }
    【解决方案2】:

    致所有仍在使用 mktime()、strtotime() 和其他 PHP 函数的人...试试 PHP5 DateTime 类。一开始我很犹豫,但它真的很容易使用。不要忘记使用 clone() 来复制您的对象。

    编辑:此代码最近被编辑以处理当前日期为星期日的情况。在这种情况下,我们必须得到过去的星期六,然后再加一天得到星期天。

    $dt_min = new DateTime("last saturday"); // Edit
    $dt_min->modify('+1 day'); // Edit
    $dt_max = clone($dt_min);
    $dt_max->modify('+6 days');
    

    然后根据需要进行格式化。

    echo 'This Week ('.$dt_min->format('m/d/Y').'-'.$dt_max->format('m/d/Y').')';
    

    确保在代码中尽早设置时区。

    date_default_timezone_set('America/New_York');
    

    【讨论】:

    • 除非我读错了,否则如果今天是星期天,我不确定这个逻辑是否可行。如果今天是星期日,并且您创建了 last sundayDateTime 对象,PHP 将返回上一个星期日,而不是当前星期日。所以如果今天的日期是 2016 年 2 月 28 日,上面的代码会回显 This week 2/21/2016 - 2/27/2016(实际上是前一周。周一到周六会隐藏这个问题。我建议像 $dt_min = new DateTime("last Saturday + 24 hour");
    【解决方案3】:

    显然 date() 的 'w' 格式值或 DateTime 对象的格式方法将以数字形式返回星期几(默认情况下,0=星期日,1=星期一等)

    您可以取这个值并从当天减去它的值作为天数来找到一周的开始。

    $start_date = new DateTime("2009-05-13");
    $day_of_week = $start_date->format("w");
    
    $start_date->modify("-$day_of_week day");
    

    $start_date 现在将等于该周的星期日,从那里您可以添加 7 天来获得一周的结束或你有什么。

    【讨论】:

    • 同样可以使用日期功能:$day_of_week date('w', strtotime($start_date));$sunday = date('Y-m-d', strtotime('-'.$day_of_week.' days', strtotime($start_date)));
    【解决方案4】:

    基于@jjwdesign 的回答,我开发了一个函数,可以使用 DateTime 类计算特定日期的一周的开始和结束。 将在 PHP 5.3.0++ 上运行

    不同之处在于您可以将所需的日期设置为 0(星期一)和 6(星期日)之间的“开始”。

    函数如下:

    if(function_exists('grk_Week_Range') === FALSE){
        function grk_Week_Range($DateString, $FirstDay=6){
            #   Valeur par défaut si vide
            if(empty($DateString) === TRUE){
                $DateString = date('Y-m-d');
            }
    
            #   On va aller chercher le premier jour de la semaine qu'on veut
            $Days = array(
                0 => 'monday',
                1 => 'tuesday',
                2 => 'wednesday',
                3 => 'thursday',
                4 => 'friday',
                5 => 'saturday',
                6 => 'sunday'
            );
    
            #   On va définir pour de bon le premier jour de la semaine     
            $DT_Min = new DateTime('last '.(isset($Days[$FirstDay]) === TRUE ? $Days[$FirstDay] : $Days[6]).' '.$DateString);
            $DT_Max = clone($DT_Min);
    
            #   On renvoie les données
            return array(
                $DT_Min->format('Y-m-d'),
                $DT_Max->modify('+6 days')->format('Y-m-d')
            );
        }
    }
    

    结果:

    print_r(grk_Week_Range('2013-08-11 16:45:32', 0));
    print_r(grk_Week_Range('2013-08-11 16:45:32', 1));
    print_r(grk_Week_Range('2013-08-11 16:45:32', 2));
    print_r(grk_Week_Range('2013-08-11 16:45:32', 3));
    print_r(grk_Week_Range('2013-08-11 16:45:32', 4));
    print_r(grk_Week_Range('2013-08-11 16:45:32', 5));
    print_r(grk_Week_Range('2013-08-11 16:45:32', 6));
    
    Array
    (
        [0] => 2013-07-29
        [1] => 2013-08-04
    )
    Array
    (
        [0] => 2013-07-30
        [1] => 2013-08-05
    )
    Array
    (
        [0] => 2013-07-31
        [1] => 2013-08-06
    )
    Array
    (
        [0] => 2013-07-25
        [1] => 2013-07-31
    )
    Array
    (
        [0] => 2013-07-26
        [1] => 2013-08-01
    )
    Array
    (
        [0] => 2013-07-27
        [1] => 2013-08-02
    )
    Array
    (
        [0] => 2013-07-28
        [1] => 2013-08-03
    )
    

    【讨论】:

    • 该功能有效。谢谢。但是,您的示例有点偏离。它的日期为 2013-08-11,那么它如何返回 7-25 到 8-06 的日期范围? 8 月 11 日不应该在某个地方吗?
    【解决方案5】:
    【解决方案6】:

    这是我的版本,它使用了与 Clay 类似的概念:

    /**
     * Start of the week
     *
     * 0 = Sun, 1 = Mon, etc.
     */
    define( 'WEEK_START', 0 );
    
    /**
     * Determine the start and end dates for
     * the week in which the specified date
     * falls
     *
     * @param $date Date in week
     * @param $start Week start (out)
     * @param $end Week end (out)
     */
    function week_bounds( $date, &$start, &$end ) {
        $date = strtotime( $date );
        // Find the start of the week, working backwards
        $start = $date;
        while( date( 'w', $start ) > WEEK_START ) {
            $start -= 86400; // One day
        }
        // End of the week is simply 6 days from the start
        $end = date( 'Y-m-d', $start + ( 6 * 86400 ) );
        $start = date( 'Y-m-d', $start );
    }
    

    经过轻微测试。代码可能不是防弹的,或者处理遥远过去或未来的日期。使用风险自负。请勿将代码浸入水中。不要将代码展示给那些有紧张情绪或讨厌美元符号的人。未在动物身上进行测试。素食者可以安全使用。作者保证代码永远不会和你说话。万一代码确实试图让您参与对话,作者建议您忽略它提供的任何和所有建议。

    【讨论】:

      【解决方案7】:

      使用它来获取任何给定日期的“周”数。

      //October 29, 2009 is my birthday
      echo $week date('W', strtotime('2009-10-29'));
      //OUTPUT: 44
      //October 29 is the 44th week in the year 2009
      

      现在将 getWeekDates 函数的参数传递为“year (2009)”和“$week”。

      function getWeekDates($year, $week, $start=true){
              $from = date("Y-m-d", strtotime("{$year}-W{$week}-1")); //Returns the date of monday in week
              $to = date("Y-m-d", strtotime("{$year}-W{$week}-7"));   //Returns the date of sunday in week
      
              if($start) {
                  return $from;
              } else {
                  return $to;
              }
              //return "Week {$week} in {$year} is from {$from} to {$to}.";
          }
      

      更多信息请参考此链接 http://blog.ekini.net/2009/07/09/php-get-start-and-end-dates-of-a-week-from-datew/

      【讨论】:

        【解决方案8】:

        在尝试找到 Paolo Bergantino 接受的答案的更简化版本时,我发现了一种非常好的方法来完成这项工作:

        function x_week_range2($date) {
          $ts = strtotime($date);
          $start = strtotime('sunday this week -1 week', $ts);
          $end = strtotime('sunday this week', $ts);
          return array(date('Y-m-d', $start), date('Y-m-d', $end));
        }
        

        “本周星期日”字符串始终表示“本周结束的星期日”。如果在星期日的时间戳上使用,它将是下一个星期日。这可以让您避免在 Paola 的解决方案中使用三元运算符。

        【讨论】:

          【解决方案9】:

          您现在可以使用 DateTime 来获取一周的开始/结束日期

          function getDateRangeForAllWeeks($start, $end){
              $fweek = getDateRangeForWeek($start);
              $lweek = getDateRangeForWeek($end);
              $week_dates = [];
              while($fweek['sunday']!=$lweek['sunday']){
                  $week_dates [] = $fweek;
                  $date = new DateTime($fweek['sunday']);
                  $date->modify('next day');
          
                  $fweek = getDateRangeForWeek($date->format("Y-m-d"));
              }
              $week_dates [] = $lweek;
          
              return $week_dates;
          }
          
          function getDateRangeForWeek($date){
              $dateTime = new DateTime($date);
              $monday = clone $dateTime->modify(('Sunday' == $dateTime->format('l')) ? 'Monday last week' : 'Monday this week');
              $sunday = clone $dateTime->modify('Sunday this week'); 
              return ['monday'=>$monday->format("Y-m-d"), 'sunday'=>$sunday->format("Y-m-d")];
          }
          

          用法

          print_r( getDateRangeForWeek("2016-05-07") );
          
          print_r( getDateRangeForAllWeeks("2015-11-07", "2016-02-15") );
          

          【讨论】:

            【解决方案10】:

            说实话,我无法理解您发布的代码;)

            我想这样的事情应该可以解决问题:

            function get_week($date) {
                    $start = strtotime($date) - strftime('%w', $date) * 24 * 60 * 60;
                    $end = $start + 6 * 24 * 60 * 60;
                    return array('start' => strftime('%Y-%m-%d', $start),
                                 'end' => strftime('%Y-%m-%d', $end));
            }
            

            【讨论】:

              【解决方案11】:

              不用做太多的字符串操作,你可以对时间戳做一些简单的数学运算。

              function getDateRange(&$start, &$end, $date) {
                $seconds_in_day = 86400;
                $day_of_week = date("w", $date); 
                $start = $date - ($day_of_week * $seconds_in_day);
                $end = $date + ((6 - $day_of_week) * $seconds_in_day);
              }
              

              【讨论】:

                【解决方案12】:

                基于 David Bélanger 的版本(不幸的是,我的代表不允许我发表评论作为对他的帖子的反应..)。

                当输入日期为星期一并且一周的第一天设置为星期一时,原始版本返回前一周,而不是当前版本。 这是小修复(与原始功能的其余部分):

                if(function_exists('grk_Week_Range') === FALSE){
                function grk_Week_Range($DateString, $FirstDay=6){
                
                    if(empty($DateString) === TRUE){
                        $DateString = date('Y-m-d');
                    }
                
                    # fix
                    $dayOfWeek = date('N', strtotime($DateString));
                    if ($dayOfWeek == ($FirstDay +1)) { $whichWeek = 'this '; }
                    else { $whichWeek = 'last '; }
                
                    $Days = array(
                        0 => 'monday',
                        1 => 'tuesday',
                        2 => 'wednesday',
                        3 => 'thursday',
                        4 => 'friday',
                        5 => 'saturday',
                        6 => 'sunday'
                    );
                
                    # fix   
                    $DT_Min = new DateTime( $whichWeek.(isset($Days[$FirstDay]) === TRUE ? $Days[$FirstDay] : $Days[6]).' '.$DateString);
                    $DT_Max = clone($DT_Min);
                
                    return array(
                        $DT_Min->format('Y-m-d'),
                        $DT_Max->modify('+6 days')->format('Y-m-d')
                    );
                }
                }
                

                【讨论】:

                  【解决方案13】:

                  返回从开始日期时间到结束日期时间的天数的简单代码。使用 gmdate() 方法可以格式化日期/时间。

                  $start_str_date = strtotime($start_date);
                  $end_str_date = strtotime($end_date);
                  $interval_days = $end_str_date - $start_str_date;
                  $days = gmdate('d',$interval_days);
                  echo $days;
                  

                  【讨论】:

                    【解决方案14】:

                    我注意到这里的大多数答案都使用了strtotime/DateTime。虽然正确,但我个人宁愿在不使用英文单词的情况下计算日期。

                    这是一个使用mtkime 的简单解决方案:

                    $now = time();
                    $day_of_week = (int)date('w', $now);
                    
                    $week_start = mktime(0, 0, 0, date('n', $now), date('j', $now)-$day_of_week, date('Y', $now));
                    $week_end = mktime(23, 59, 59, date('n', $week_start), date('j', $week_start)+6, date('Y', $week_start));
                    

                    【讨论】:

                      【解决方案15】:
                      function weekRange($year, $week){
                              $dateFrom = new \DateTime();
                              $dateFrom->setISODate($year, $week);
                              $dateTo = new \DateTime();
                              $dateTo->setISODate($year, $week, 7);
                      
                              return array(
                                  'week' => $dateFrom->format('Y-W'),
                                  'start'=> $dateFrom->format('Y-m-d'),
                                  'end' => $dateTo->format('Y-m-d')
                              );
                          }
                      

                      例子:

                      $weekInformation = weekRange(2020, 38);
                      
                      echo $weekInformation['start']; 
                      // Display: 2020-09-14
                      
                      echo $weekInformation['end']; 
                      // Display: 2020-09-20
                      

                      【讨论】:

                        【解决方案16】:

                        来自 PHP 日期时间文档:

                        <?php
                        $date = new DateTime();
                        
                        $date->setISODate(2008, 2);
                        $startDay = $date->format('Y-m-d');
                        
                        $date->setISODate(2008, 2, 7);
                        $endDay = $date->format('Y-m-d');
                        ?>
                        

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2018-10-05
                          • 1970-01-01
                          相关资源
                          最近更新 更多