【问题标题】:PHP get start and end date of a week by weeknumberPHP通过weeknumber获取一周的开始和结束日期
【发布时间】:2011-06-19 04:24:26
【问题描述】:

我已经看到了这个问题的一些变体,但我相信这个问题还没有得到回答。

我需要获取一周的开始日期和结束日期,按年份和周数(不是日期)选择

示例:

输入:

getStartAndEndDate($week, $year);

输出:

$return[0] = $firstDay;
$return[1] = $lastDay;

返回值类似于一个数组,其中第一个条目是周开始日期,第二个条目是结束日期。

可选:当我们使用它时,日期格式需要为Y-n-j(正常日期格式,没有前导零。

我已经尝试编辑现有的功能,几乎可以达到我想要的效果,但到目前为止我没有运气。

请帮帮我,提前谢谢。

【问题讨论】:

  • StackOverflow 并不是要覆盖尽可能多的变体。如果您能够从变体中找出解决方案,请不要问这个问题。如果您无法弄清楚,我们鼓励您解释您从变体中获得了多远。

标签: php date


【解决方案1】:

使用DateTime 类:

function getStartAndEndDate($week, $year) {
  $dto = new DateTime();
  $dto->setISODate($year, $week);
  $ret['week_start'] = $dto->format('Y-m-d');
  $dto->modify('+6 days');
  $ret['week_end'] = $dto->format('Y-m-d');
  return $ret;
}

$week_array = getStartAndEndDate(52,2013);
print_r($week_array);

返回:

Array
(
    [week_start] => 2013-12-23
    [week_end] => 2013-12-29
)

解释:

  • 创建一个默认为 now() 的新 DateTime 对象
  • 调用 setISODate 将对象更改为 $year 的 $week 的第一天,而不是 now()
  • 将日期格式化为“Y-m-d”并放入 $ret['week_start']
  • 通过添加 6 天修改对象,这将是 $week 的结束
  • 将日期格式化为“Y-m-d”并放入 $ret['week_end']

更短的版本(适用于 >= php5.3):

function getStartAndEndDate($week, $year) {
  $dto = new DateTime();
  $ret['week_start'] = $dto->setISODate($year, $week)->format('Y-m-d');
  $ret['week_end'] = $dto->modify('+6 days')->format('Y-m-d');
  return $ret;
}

可以在 >= php5.4 中使用 class member access on instantiation 缩短。

【讨论】:

  • 这应该是公认的答案,放下手。它更快、更干净,并且利用了内部 DateTime() 类。
  • 请注意,如果您决定传回 DateTime 对象,则需要在这样做之前添加克隆,否则您将始终取回修改后的日期。 $ret['week_start'] = clone $dto;
  • 因为 mysql 有时需要这个,所以我们也需要时间。所以我稍微修改了一下。重置时间,增加 7 天并减少 1 秒。 $dto = 新日期时间(); $dto->setISODate($year, $week); $dto->setTime(0,0,0); $ret['week_start'] = $dto->format('Y-m-d H:i:s'); $dto->modify('+7 天'); $dto->modify('-1 秒'); $ret['week_end'] = $dto->format('Y-m-d H:i:s');
  • 接受的答案是休息一周,其中有一些错误,这个有效
【解决方案2】:

多年前,我发现了这个功能:

function getStartAndEndDate($week, $year) {
  $dto = new DateTime();
  $dto->setISODate($year, $week);
  $ret['week_start'] = $dto->format('Y-m-d');
  $dto->modify('+6 days');
  $ret['week_end'] = $dto->format('Y-m-d');
  return $ret;
}

$week_array = getStartAndEndDate(52,2013);
print_r($week_array);

【讨论】:

    【解决方案3】:

    除了DateTime 类固有的计算之外,我们无需额外计算即可轻松实现这一目标。

    function getStartAndEndDate($year, $week)
    {
       return [
          (new DateTime())->setISODate($year, $week)->format('Y-m-d'), //start date
          (new DateTime())->setISODate($year, $week, 7)->format('Y-m-d') //end date
       ];
    }
    

    setISODate() 函数接受三个参数:$year$week$day,其中 $day 默认为 1 - 一周的第一天。因此,我们通过 7 来获得 $week 的第 7 天的确切日期。

    【讨论】:

      【解决方案4】:

      稍微简洁的解决方案,使用 "[year]W[week][day]" strtotime 格式:

      function getStartAndEndDate($week, $year) {
        // Adding leading zeros for weeks 1 - 9.
        $date_string = $year . 'W' . sprintf('%02d', $week);
        $return[0] = date('Y-n-j', strtotime($date_string));
        $return[1] = date('Y-n-j', strtotime($date_string . '7'));
        return $return;
      }
      

      【讨论】:

        【解决方案5】:

        最短的方法:

        function week_date($week, $year){
            $date = new DateTime();
            return "first day of the week is ".$date->setISODate($year, $week, "1")->format('Y-m-d')
            ."and last day of the week is ".$date->setISODate($year, $week, "7")->format('Y-m-d'); 
        }
        echo week_date(12,2014);
        

        【讨论】:

          【解决方案6】:

          您可以从以下日期获取具体的星期几,我得​​到第一天和最后一天

          $date = date_create();
          
          // get the first day of the week
          date_isodate_set($date, 2019, 1);
          
              //convert date format and show     
              echo date_format($date, 'Y-m-d') . "\n";
          
          // get the last date of the week
          date_isodate_set($date, 2019, 1, 7);
          
               //convert date format and show        
               echo date_format($date, 'Y-m-d') . "\n";
          

          输出 =>

          2018-12-31

          2019-01-06

          【讨论】:

            【解决方案7】:

            Roham Rafii 的计算是错误的。这是一个简短的解决方案:

            // week number to timestamp (first day of week number)
            function wn2ts($week, $year) {
                return strtotime(sprintf('%dW%02d', $year, $week));
            }
            

            如果要一周最后一天的编号,可以加6 * 24 * 3600

            【讨论】:

              【解决方案8】:

              这是一个老问题,但上面发布的许多答案似乎都不正确。 我想出了自己的解决方案:

              function getStartAndEndDate($week, $year){
                  $dates[0] = date("Y-m-d", strtotime($year.'W'.str_pad($week, 2, 0, STR_PAD_LEFT)));
                  $dates[1] = date("Y-m-d", strtotime($year.'W'.str_pad($week, 2, 0, STR_PAD_LEFT).' +6 days'));
                  return $dates;
              }
              

              【讨论】:

                【解决方案9】:

                首先我们需要那一周的一天,所以通过知道周数并知道一周有 7 天,我们将这样做

                $pickADay = ($weekNo-1) * 7 + 3;
                

                这样 pickAday 将是我们想要的一周中的一天。

                现在因为我们知道年份,所以我们可以检查那是哪一天。 如果我们只需要比 unix 时间戳更新的日期,事情就很简单了 我们将获取一年中第一天的 unix 时间戳并将其添加到 24*3600*$pickADay 并且从这里开始一切都很简单,因为我们有它的时间戳,我们可以知道它是一周中的哪一天并计算该周的头部和尾部相应地。

                如果我们想找出相同的事情,比如说 1848 年的第 12 周,我们必须使用另一种方法,因为我们无法获得时间戳。知道每年一天提前 1 个工作日的含义(去年 11 月 1 日是星期日,今年是星期一,我相信闰年会提前 2 天例外,你可以检查一下)。如果年份早于 1970 年,我会做什么,而不是在它和需要的年份之间产生差异,以了解那里有多少年,计算一周中的哪一天,因为我的 pickADay 是 1970 年的一部分,每个工作日将其移回一个工作日. $shiftTimes = ($yearDifference + $numberOfLeapYears)%7,不同之处。 shift the day backwords $shiftTimes,那么你就会知道几年前那一天是星期几,然后找到weekhead和weektail。如果看起来更简单,同样的东西也可以用于未来。如果它有效,请尝试它,并告诉我它是否无效。

                【讨论】:

                • 谢谢,它确实消除了我对这些日期的一些困惑。 Roham Rafii 给出的答案证实了你的理论,我非常感谢你们!
                【解决方案10】:

                对于文档(因为谷歌在搜索“php datetime start end this week”时将这个问题排在第一位)。

                如果您需要当前周的开始日期和结束日期(使用日期时间):

                $dateTime = new DateTime('now');
                $monday = clone $dateTime->modify(('Sunday' == $dateTime->format('l')) ? 'Monday last week' : 'Monday this week');
                $sunday = clone $dateTime->modify('Sunday this week');
                
                var_dump($monday->format('Y-m-d')); // e.g. 2018-06-25
                var_dump($sunday->format('Y-m-d')); // e.g. 2018-07-01
                

                希望这会有所帮助。

                【讨论】:

                  【解决方案11】:

                  你试过PHP relative dates吗?它可能会起作用。

                  【讨论】:

                  • 那么您建议我使用什么命令? strtotime('first day of week 12')?
                  • 也许你可以把它们串起来。尝试+n weeks 来获得一周。然后再次查看文档。还有一种获得工作日的方法。
                  【解决方案12】:

                  即使您不想使用特定日期,也无法逃避它。您可以仅根据日期计算一周。

                  步骤:

                  1. 获取一年的第一天
                  2. 决定第一周的开始时间(如果我记得的话,有些规则包括第一个星期四。
                  3. 添加一些周数(您的第一个参数)。 Zend_Date 有一个 add() 函数,例如,您可以在其中添加星期。这将为您提供一周的第一天。
                  4. 偏移并获得最后一天。

                  我建议使用一致的日期系统,例如 Zend_DatePear Date

                  【讨论】:

                    【解决方案13】:
                    function getStartAndEndDate($week, $year)
                        {
                            $week_start = new DateTime();
                            $week_start->setISODate($year,$week);
                            $return[0] = $week_start->format('d-M-Y');
                            $time = strtotime($return[0], time());
                            $time += 6*24*3600;
                            $return[1] = date('d-M-Y', $time);
                            return $return;
                        }
                    

                    【讨论】:

                    • 解释一下你做了什么,而不是简单地发布代码
                    【解决方案14】:
                    $dateParam = '2018-06-10';
                    $week = date('w', strtotime($dateParam));
                    $date = new DateTime($dateParam);
                    $firstWeek = $date->modify("-".$week." day")->format("Y-m-d H:i:s");
                    $endWeek = $date->modify("+6 day")->format("Y-m-d H:i:s");
                    echo $firstWeek."<br/>";
                    echo $endWeek;
                    

                    将打印

                    2018-06-10 00:00:00
                    2018-06-16 00:00:00
                    

                    希望能有所帮助

                    【讨论】:

                      【解决方案15】:

                      “一周的第一天”是主观的。有些文化使用“星期一”,有些使用“星期日”,也许其他文化使用其他?

                      出于我的目的,我希望一周的第一天是“星期日”,一周的最后一天是“星期六”。

                      此外,使用不带参数的DateTime 将默认为“现在”,其中包括当前时间。以下方法将通过在 DateTime 构造函数中指定“今天”来忽略当前时间。

                      此外,字符串“本周日”似乎并不可靠。它实际上会在下周星期天返回(根据我对一周的看法)。

                      我构建了一个方法,它返回一个包含两个 DateTime 对象的 PHP 对象。一个用于给定周的第一天(星期日),第二个用于给定周的最后一天(星期六)。

                      function get_first_and_last_day_of_week( $year_number, $week_number ) {
                          // we need to specify 'today' otherwise datetime constructor uses 'now' which includes current time
                          $today = new DateTime( 'today' );
                      
                          return (object) [
                              'first_day' => clone $today->setISODate( $year_number, $week_number, 0 ),
                              'last_day'  => clone $today->setISODate( $year_number, $week_number, 6 )
                          ];
                      }
                      

                      【讨论】:

                        猜你喜欢
                        • 2018-10-05
                        • 1970-01-01
                        • 2021-01-18
                        • 2010-11-19
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2017-08-02
                        • 1970-01-01
                        相关资源
                        最近更新 更多