У меня есть код, который проходит каждый день в пределах 10-летнего диапазона, начиная с определенной даты. Дата должна быть добавлена только в том случае, если она соответствует выбранным критериям из формы.Определение даты является частью каждой недели в зависимости от даты начала.
В форме есть поля для месяцев и дней недели. В течение каждого буднего дня есть варианты для каждого, первого, второго и т. Д. Я добавляю «каждый другой» вариант в каждый будний день вместе с полем даты начала.
Я пытаюсь определить лучший способ проверить, соответствует ли текущая дата критериям «друг друга» на основе даты начала.
Рассмотрев другие вопросы, я не смог найти идеальный ответ, который учитывал бы год, который имеет 53 недели. Я смог придумать некоторый тестовый код, который, кажется, дает мне точные результаты, но мне интересно, есть ли более простой способ выполнить эту проверку.
Код проверки:
// set start date
$date = new \DateTime('2019-12-15');
// get start date week of year and modulus
$start_week = date('W', $date->getTimestamp());
$start_mod = $start_week % 2;
// set end time (10 years from start date)
$end_time = strtotime('+10 years', $date->getTimestamp());
// init previous year and week modifier
$prev_year = false;
$week_modifier = 1;
// each day in range
while($date->getTimestamp() <= $end_time){
// get year
$y = $date->format('Y');
// previous year doesn't match current year
if($prev_year != $y){
// previous year set
if($prev_year){
// get number of weeks in year
$weeks_in_year = date('W', mktime(0, 0, 0, 12, 28, $prev_year));
// year has odd number of weeks
if($weeks_in_year % 2){
// increment week modifier
$week_modifier++;
}
}
// update previous year
$prev_year = $y;
}
// get week of year
$w = $date->format('W') + $week_modifier;
// check if meets every other criteria (based on start date)
$every_other = false;
if(($w % 2) == $start_mod){
$every_other = true;
}
// print date if it is part of every other Tuesday
if($date->format('w') == 2 && $every_other){
echo $date->format('Y-m-d');
echo '<br/>';
}
// increment day
$date->modify('+1 day');
}
Примечание 1: 2020 в следующем году, в котором есть 53 недель.
Примечание 2: У меня была опечатка в этом тестовом коде, который был увеличивающимся модификатор недели вместо его инициализации в 0. Это имело бы больше смысла для меня, что этот код будет работать, если модификатор был инициализирован равным 0 , но вместо этого он работает только при инициализации нечетного числа.
Я бы рассмотрите этот проект: https://github.com/simshaun/recurr, который очень хорош для обработки повторения, это показывает некоторые примеры строк RRULE, которые вы можете использовать: http://www.kanzaki.com/docs/ical/ rrule.html – Theo
... вырезанная версия строки для каждого другого понедельника выглядит так: FREQ = WEEKLY; INTERVAL = 2; BYDAY = MO' (вы можете включать даты начала и окончания и многое другое) – Theo
Спасибо @ Theo. Я не знал о Рекурре. Я определенно буду более внимательно рассматривать это для решения этой и нескольких других проблем с датами! –