我很确定我过于复杂,但我不知道如何以另一种方式做到这一点。
我想创建一个数组,其中包含一个月中一周的数字作为键,以及本周的日期作为值。
我使用此功能来获取一周的所有日子:
public function getDaysOfWeek($year, $month, $day)
{
$firstMondayThisWeek = new DateTime($year . '/' . $month . '/' . $day, new DateTimeZone("Europe/Berlin"));
$firstMondayThisWeek->modify('tomorrow');
$firstMondayThisWeek->modify('last Monday');
$nextSevenDays = new DatePeriod(
$firstMondayThisWeek,
DateInterval::createFromDateString('+1 day'),
6
);
return $nextSevenDays;
}
这个函数构建数组:
public function getWeekAndDays($year, $month)
{
$weeksInMonth = Carbon::createFromDate($year, $month)->endOfMonth()->weekOfMonth;
$weekBegin = Carbon::createFromDate($year, $month)->startOfMonth();
$weeks = [];
for($i=1; $i<=$weeksInMonth; $i++)
{
$collection = new \stdClass();
$collection->week = $i;
$collection->days = $this->getDaysOfWeek($year, $month, $weekBegin->day);
$weekBegin->addWeek(0);
$weeks[] = $collection;
}
return $weeks;
}
除了2月份之外的所有月份,我都会有5周的时间。对于2月份,我有4周的时间,所以我无法保存月份重叠的日子。
我在这里完全错了吗?有什么方法可以解决这个问题?
答案 0 :(得分:6)
我的朋友感觉到你的痛苦,使用日历数据很烦人。这是我之前写过的一个函数,它构建了一个数周和数天的数组,以数月分隔。它不是最干净的代码,但它有效。
它将从您传递到$today
的日期开始,作为&#34; Y-m-d&#34; (或默认为当前日期),然后返回当前月的第一周,从那里开始,然后继续$scheduleMonths
个月建立一个按月索引,然后按周索引的数组。
这里有点难以解释,但它是自包含的,所以您可以将其复制/粘贴到您的代码中,然后dd()
输出以查看它的外观和如果它适合你,并从那里修改它。您可能需要调整一些格式,因为它是针对我的特定用例而做的,但业务逻辑应该是合理的。
您应该能够从输出中提取给定月份的周数(因此,如果您需要的话,只要您确认它正常工作,就可以简化此操作)。
public function getWeeks($today = null, $scheduleMonths = 6) {
$today = !is_null($today) ? Carbon::createFromFormat('Y-m-d',$today) : Carbon::now();
$startDate = Carbon::instance($today)->startOfMonth()->startOfWeek()->subDay(); // start on Sunday
$endDate = Carbon::instance($startDate)->addMonths($scheduleMonths)->endOfMonth();
$endDate->addDays(6 - $endDate->dayOfWeek);
$epoch = Carbon::createFromTimestamp(0);
$firstDay = $epoch->diffInDays($startDate);
$lastDay = $epoch->diffInDays($endDate);
$week=0;
$monthNum = $today->month;
$yearNum = $today->year;
$prevDay = null;
$theDay = $startDate;
$prevMonth = $monthNum;
$data = array();
while ($firstDay < $lastDay) {
if (($theDay->dayOfWeek == Carbon::SUNDAY) && (($theDay->month > $monthNum) || ($theDay->month == 1))) $monthNum = $theDay->month;
if ($prevMonth > $monthNum) $yearNum++;
$theMonth = Carbon::createFromFormat("Y-m-d",$yearNum."-".$monthNum."-01")->format('F Y');
if (!array_key_exists($theMonth,$data)) $data[$theMonth] = array();
if (!array_key_exists($week,$data[$theMonth])) $data[$theMonth][$week] = array(
'day_range' => '',
);
if ($theDay->dayOfWeek == Carbon::SUNDAY) $data[$theMonth][$week]['day_range'] = sprintf("%d-",$theDay->day);
if ($theDay->dayOfWeek == Carbon::SATURDAY) $data[$theMonth][$week]['day_range'] .= sprintf("%d",$theDay->day);
$firstDay++;
if ($theDay->dayOfWeek == Carbon::SATURDAY) $week++;
$theDay = $theDay->copy()->addDay();
$prevMonth = $monthNum;
}
$totalWeeks = $week;
return array(
'startDate' => $startDate,
'endDate' => $endDate,
'totalWeeks' => $totalWeeks,
'schedule' => $data,
);
}
我希望这可以帮助你至少开始!
答案 1 :(得分:0)
这样的东西?
function weekOfMonth($date) {
$firstOfMonth = strtotime(date("Y-m-01", $date));
$lastWeekNumber = (int)date("W", $date);
$firstWeekNumber = (int)date("W", $firstOfMonth);
if (12 === (int)date("m", $date)) {
if (1 == $lastWeekNumber) {
$lastWeekNumber = (int)date("W", ($date - (7*24*60*60))) + 1;
}
} elseif (1 === (int)date("m", $date) and 1 < $firstWeekNumber) {
$firstWeekNumber = 0;
}
return $lastWeekNumber - $firstWeekNumber + 1;
}
function weeks($month, $year){
$lastday = date("t", mktime(0, 0, 0, $month, 1, $year));
return weekOfMonth(strtotime($year.'-'.$month.'-'.$lastday));
}
$result = [];
for ($year = 2017; $year < 2020; $year++){
for ($month = 1; $month < 13; $month++) {
$numOfWeeks = weeks($month, $year);
$result[$year][$month]['numOfWeeks'] = $numOfWeeks;
$daysInFirstWeek = 8 - date('N', strtotime($year.'-'.$month.'-01'));
$result[$year][$month]['daysPerWeek']['week_1'] = $daysInFirstWeek;
$startDay = date('d', strtotime('next Monday', strtotime($year.'-'.$month.'-01')));
for ($i = 1; $i < ($numOfWeeks - 1); $i++) {
$startDay += 7;
$result[$year][$month]['daysPerWeek']['week_'.($i+1)] = 7;
}
//last week
$result[$year][$month]['daysPerWeek']['week_'.($i+1)] = date('t', strtotime($year.'-'.$month.'-01')) - $startDay + 1;
}
}
echo json_encode($result)."\n";