laravel 如何使用DateTime返回空闲天数的数组

gmol1639  于 2023-01-06  发布在  其他
关注(0)|答案(3)|浏览(108)

我正在使用Laravel 9创建课程安排器,
我试过了,但我有点迷失,

$free_time_frame = [[]];  // nested array here

$start = new DateTime("2023-01-01");
$end = new DateTime("2023-12-31");

$interval = new DateInterval("P1D"); // 1 month interval
$period = new DatePeriod($start, $interval, $end);
$seasons = ["2023-02-01", "2023-02-13"];
foreach ($period as $date) {
  if (in_array($date->format("Y-m-d"), $seasons)) {
    // Skip the rest of the loop if the current month is in the $seasons array
    $free_time_frame[] = [];   // append nested array
    continue;
  }

  // Set the start date to the first day of the month
  $start_date = new DateTime($date->format("Y-m-01"));
  // Set the end date to the last day of the month
  $end_date = new DateTime($date->format("Y-m-t"));

  // Calculate the number of days between the start and end dates
  $diff = $start_date->diff($end_date);
  $days = $diff->days + 1; // Add 1 to include the end date

  // use the latest nested array
  

}

我正在预订$seasons,我希望在"2023-02-01"之前和"2023-02-13"之后有一个免费天数的数组,如下所示:
预期结果

[
  [
   "2023-01-01",
   "2023-01-02",
   "2023-01-03",
   "..."
   "2023-01-31",
  ]
  [
   "2023-02-14",
   "2023-02-15",
   "2023-02-16",
   "2023-02-14",
   "and so on util the end of the year"
  ]
]

先谢谢你的帮助

guykilcj

guykilcj1#

好的,我想我明白了,你想得到一个日期范围内的所有日期,然后排除特定的日期范围。

你可以这样做:

$originalDates = \Carbon\CarbonPeriod::between('2023-01-01', '2023-01-10')->toArray();
$excludedDates = \Carbon\CarbonPeriod::between('2023-01-03', '2023-01-06')->toArray();
        
$finalDates = [];
        
foreach ($originalDates as $date) {
    if(!in_array($date, $excludedDates)){
        array_push($finalDates, $date->format('d-m-Y'));
    }
}
    
return $finalDates;

这将返回以下结果的数组:

01-01-2023
02-01-2023
07-01-2023
08-01-2023
09-01-2023
10-01-2023

请注意,它从2023-01-03跳到了2023-01-06
您可以根据自己的喜好格式化它,方法是更改$date->format('d-m-Y')行,以您想要的方式表示结果,您甚至可以删除该格式以返回一个碳数组,您可以在其他地方根据自己的喜好解析该数组。
您可以更进一步,拥有多个excludedDates,并检查它们是否为in_array
希望这能有所帮助,如果你想进一步澄清或修改,请添加评论。

l2osamch

l2osamch2#

要计算$seasons中不包括中间时间段的空闲时间,只需计算seasons数组第一个元素之前的所有内容和seasons数组最后一个元素之后的所有内容。
因此,只需在这些范围内运行2个DatePeriod循环即可实现这一点。

<?php

$seasons = ["2023-02-01", "2023-02-13", "2023-03-16"];

$free_time_frame = [];

$free_time_frame[] = getDaysInPeriod('2023-01-01', 'P1D', current($seasons));
$free_time_frame[] = getDaysInPeriod(date("Y-m-d", strtotime(end($seasons). " +1 days")), 'P1D', '2024-01-01');

function getDaysInPeriod($startDate, $dateInterval, $endDate){
  $span = [];
  foreach(new DatePeriod(new DateTime($startDate), new DateInterval($dateInterval),new DateTime($endDate)) as $p){
    $span[] = $p->format('Y-m-d');
  }
  return $span;
}

$free_time_frame = array_filter($free_time_frame);

print_r($free_time_frame);

Online Fiddle

idv4meu8

idv4meu83#

我认为你可以做到以下几点:

$startDate = '2023-01-01';
$endDate = '2023-03-31';

$seasons = ['2023-02-01', '2023-02-13'];

$prepareSeasons = [
    [ $startDate, Carbon::parse($seasons[0])->subDay()->format('Y-m-d') ],
    [ Carbon::parse($seasons[0])->addDay()->format('Y-m-d'), $endDate ]
];

// this is want we want to achieve
// $prepareSeasons = [
//     [$startDate, '2023-01-31'],
//     ['2023-02-14', $endDate],
// ];

$freeTimeFrame = [];

foreach ($prepareSeasons as $seasonDates)
{
    $freeSeason = [];

    $seasonDates = CarbonPeriod::create($seasonDates[0], $seasonDates[1])->toArray();

    foreach ($seasonDates as $date)
    {
        array_push($freeSeason, $date->format('Y-m-d'));
    }

    array_push($freeTimeFrame, $freeSeason);
}

return $freeTimeFrame;

上面的代码将达到您预期的结果

[
  [
   "2023-01-01",
   "2023-01-02",
   "2023-01-03",
   "...",
   "...",
   "2023-01-31",
  ],
  [
   "2023-02-14",
   "2023-02-15",
   "2023-02-16",
   "2023-02-14",
   "...",
   "...",
   "2023-12-31",
  ]
]

希望这能帮到你。

相关问题