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



我使用的是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"
]
]

谢谢你的帮助

要从不包括中间时间段的$seasons计算空闲时间,它只是季节数组的第一个元素之前的所有内容和季节数组的最后一个元素之后的所有内容。

因此,要实现这一点,只需在这些范围内运行两次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);

在线小提琴

我认为你可以这样做:

$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",
]
]

我希望这对你有帮助。

好了,我想我明白了,您想要获得一系列日期之间的所有日期,然后排除特定日期范围。

你可以这样做:

$originalDates = CarbonCarbonPeriod::between('2023-01-01', '2023-01-10')->toArray();
$excludedDates = CarbonCarbonPeriod::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

希望这对你有帮助,如果你想进一步澄清或修改,请添加评论。

最新更新