简体   繁体   English

PHP 如何根据日期范围获取一周的第一天和最后一天

[英]PHP How to get first and last day of a week based on date range

I have a function that can return first day and last day of a week based on date range given but apparently I got some problems in the function as it will return 8 days per week in an array and how can I set the end date of a week to Sunday as now the end date is Monday.我有一个 function 可以根据给定的日期范围返回一周的第一天和最后一天,但显然我在 function 中遇到了一些问题,因为它将在数组中每周返回 8 天,我该如何设置周到周日,因为现在结束日期是周一。

PHP: PHP:

    private function rangeWeek(string $start,string $end): array
    {
        $start     = new DateTime($start);
        $end       = new DateTime($end);
        $interval  = new DateInterval('P1D');
        $period    = new DatePeriod($start, $interval, $end);
        $weeks     = [];
        $oldWeek   = null;
        $weekStart = null;
        foreach ($period as $date) {
            $week = $date->format('W');
            if ($week !== $oldWeek) {
                if (null === $weekStart) {
                    $oldWeek   = $week;
                    $weekStart = $date->format('Y-m-d');
                } else {
                    $weeks[]   = ['start' => $weekStart, 'end' => $date->format('Y-m-d'), 'week' => $week];
                    $weekStart = null;
                }
                continue;
            }
        }

        $weeks[] = ['start' => $weekStart, 'end' => $end->format('Y-m-d'), 'week' => $week];
        return $weeks;
    }

$startDate = '2022-08-08'; //Monday
$endDate   = '2022-08-23'; //Tuesday
$weeks     = rangeWeek($startDate, $endDate);
print_r($weeks);

Output: Output:

Array
(
    [0] => Array //This array return 8 days per week
        (
            [start] => 2022-08-08 //Monday
            [end] => 2022-08-15   //Monday (should be end on Sunday)
            [week] => 33
        )

    [1] => Array
        (
            [start] => 2022-08-16 //Tuesday (Should be start on Monday)
            [end] => 2022-08-22  //Monday (should be end on Sunday)
            [week] => 34
        )

    [2] => Array
        (
            [start] => null
            [end] => 2022-08-23
            [week] => 34
        )

)

Expected Output:预期 Output:

Array
(
    [0] => Array
        (
            [start] => 2022-08-08 //Monday
            [end] => 2022-08-14   //Sunday
            [week] => 33
        )

    [1] => Array
        (
            [start] => 2022-08-15 //Monday
            [end] => 2022-08-21  //Sunday
            [week] => 34
        )

    [2] => Array
        (
            [start] => 2022-08-22 //Monday
            [end] => 2022-08-23   //Tuesday
            [week] => 35 
        )

)

I'm adding a simple post here with a PHP method that has helped me.我在这里添加了一个简单的帖子,其中包含对我有帮助的 PHP 方法。 This method calculates the beginning and ending of a week given the year and week number此方法根据年份和周数计算一周的开始和结束

To add to the confusion, PHP's methods themselves seem confused about what the first and last day of the week are.更令人困惑的是,PHP 的方法本身似乎对一周的第一天和最后一天是什么感到困惑。

For example:例如:

$new_date = new DateTime;
// returns Monday, Jan 29 2018
$new_date->setISODate(2018, 5);

// returns Sunday, Feb 4 2018
$new_date->modify('sunday this week');

// returns Sunday, Jan 28 2018
$new_date->setISODate(2018, 5 ,0);

The method below is the one I've found returns the most helpful results:下面的方法是我发现返回最有用的结果的方法:

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 )
    ];
}

I written a sample code.我写了一个示例代码。

I using monday this week to get start of week and sunday this week to get end of week.我用monday this week来开始一周,用本周的sunday this week来结束一周。

<?php

    function rangeWeek(string $start,string $end)
    {
        $start     = new DateTime($start);
        $end       = new DateTime($end);
        $interval  = new DateInterval('P1D');
        $period    = new DatePeriod($start, $interval, $end);
        $weeks     = [];
        $oldWeek   = null;
        $weekStart = null;
        foreach ($period as $date) {
            $week = $date->format('W');
            
            if(!isset($weeks[$week]))
            {
                 $weekStart = date("Y-m-d", strtotime('monday this week', strtotime($date->format('Y-m-d'))));
                $weekEnd = date("Y-m-d", strtotime('sunday this week', strtotime($date->format('Y-m-d'))));
                 $weeks[$week]   = ['start' => $weekStart, 'end' => $weekEnd, 'week' => $week];
            }
        }
        return $weeks;
    }

$startDate = '2022-08-08'; //Monday
$endDate   = '2022-08-23'; //Tuesday
$weeks     = rangeWeek($startDate, $endDate);
print_r($weeks);

You don't need to keep track of the week number but rather just Mondays and Sundays as a pair like below:您不需要跟踪周数,而只需跟踪周一和周日,如下所示:

Snippet:片段:

<?php


function rangeWeek(string $start,string $end): array{
    $start     = new DateTime($start);
    $end       = new DateTime($end);
    $interval  = new DateInterval('P1D');
    $period    = new DatePeriod($start, $interval, $end);
    $weeks     = [];
    $monday    = null;
    foreach ($period as $currentDay) {
       if($currentDay->format('D') == 'Mon'){
         $monday = $currentDay;
       }else if($currentDay->format('D') == 'Sun'){
          $weeks[] = [
            'start' => is_null($monday) ? null : $monday->format('Y-m-d'),
            'end' => $currentDay->format('Y-m-d'),
            'week' => $currentDay->format('W')
          ];
          $monday = null;
       }
    }
    
    return array_merge($weeks, [[
        'start' => is_null($monday) ? null : $monday->format('Y-m-d'),
        'end' => $end->format('Y-m-d'),
        'week' => $end->format('W')
      ]]);
}

$startDate = '2022-08-08'; //Monday
$endDate   = '2022-08-23'; //Tuesday
$weeks     = rangeWeek($startDate, $endDate);
print_r($weeks);

Online Demo在线演示

Without DateInterval , the modify method of DateTime can be used to go from the current day to the next Sunday and then to the following Monday.如果没有DateInterval ,则可以使用 DateTime 的 modify 方法从当天到下周日再到下周一 go 。

function rangeWeek(string $start,string $end): array{
  $dtStart = date_create($start);
  $dtEnd = date_create($end);
  $weeks = [];
  while($dtStart <= $dtEnd){
    $weeks[] = [
      'start' => $dtStart->format('Y-m-d'),
      'end' => min($dtEnd,$dtStart->modify('Sunday this week'))->format('Y-m-d'),
      'week' => $dtStart->format('W')
    ];
  $dtStart->modify('next Monday');
  }
  return $weeks;
}

$startDate = '2022-08-08'; //Monday
$endDate   = '2022-08-23'; //Tuesday
$weeks     = rangeWeek($startDate, $endDate);
var_dump($weeks);

Demo: https://3v4l.org/ouK2q演示: https://3v4l.org/ouK2q

Using min replaces the if queries to test if the next Sunday is after the end date.使用min替换 if 查询以测试下周日是否在结束日期之后。 min can be used since DateTime objects can be directly compared.可以使用min ,因为可以直接比较 DateTime 对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM