我正在研究客户调度程序,我的雇主希望它每年自动重新安排客户。他希望他们每年保持同一周的同一天。
例如,客户计划于2014年5月23日举行。这是5月的第四个周五。 2014年5月23日过后,应预订2015年5月4日的预约(在本案例中为第22次)。
我已经尝试过各种各样的方法来实现这一点(例如使用DateTime提前一年,找到一周中任何一天的“之前”)。但是,我尝试过的每一款车型在短短几年后都会出现故障。他们最终会像...这个月的第二个星期五一样。
有没有人有办法让这个工作?我的雇主非常具体地希望调度程序以这种方式工作。 x.x如果有人知道如何,我真的很感激帮助。
感谢您阅读本文!
答案 0 :(得分:6)
正如已经指出的那样,例如,可能没有6月的第5个星期五,所以需要有一些标准的方法来决定明年哪一周与当前星期相同。
实际上已经有ISO 8601中的周编号标准,PHP的DateTime class内置了处理它们的功能。
我的建议是在下一年ISO 8601 week number
安排同一天的下一次会议。以下功能将为您完成: -
/**
* @param \DateTime $date Date of the original meeting
* @return \DateTime Date of the next meeting
*/
function getSameDayNextYear(\DateTime $date = null)
{
if(!$date){
$date = new \DateTime();
}
return (new \DateTime())->setISODate((int)$date->format('o') + 1, (int)$date->format('W'), (int)$date->format('N'));
}
See it working with some test code
我相信你会同意这是最简单的方法,而且应该看到你正确的next 100 years or more:)
答案 1 :(得分:0)
我认为这将满足您的需求。不过,你需要对它进行彻底的测试才能确定。
$event = new DateTime('2014-05-18');
$dayOfWeek = $event->format('l');
if ($dayOfWeek !== 'Sunday') {
$event->modify('previous Sunday');
}
else {
$event->modify('-1 day');
}
$event->modify('+1 year');
if ($dayOfWeek !== 'Sunday' && $dayOfWeek !== $event->format('l')) {
$event->modify('next ' . $dayOfWeek);
}
echo $event->format('Y-m-d');
答案 2 :(得分:0)
将您的要求更改为"添加一年并找到一周的下一个匹配日"我想出了这个:
function nextDate($date = false){
if(!$date){ $date = new DateTime(); }
$oneYear = new DateInterval('P1Y');
$dayOfWeek = $date->format('w');
$nextDate = clone $date;
$nextDate->add($oneYear);
$nextYearDayOfWeek = $nextDate->format('w');
while($nextYearDayOfWeek != $dayOfWeek){
// add a day and check again
$nextDate->add(new DateInterval('P1D'));
$nextYearDayOfWeek = $nextDate->format('w');
}
return $nextDate;
}
我的测试:
$test1 = new DateTime('5/23/2014');
$test2 = new DateTime('5/24/2014');
$test3 = new DateTime('5/25/2014');
$test4 = new DateTime('5/26/2014');
$test5 = new DateTime('5/27/2014');
$test6 = new DateTime('5/28/2014');
$test7 = new DateTime('5/29/2014');
$test8 = new DateTime('1/1/2014');
$test9 = new DateTime('12/31/2014');
$test10 = new DateTime('5/5/2040');
$nextDate1 = nextDate($test1);
$nextDate2 = nextDate($test2);
$nextDate3 = nextDate($test3);
$nextDate4 = nextDate($test4);
$nextDate5 = nextDate($test5);
$nextDate6 = nextDate($test6);
$nextDate7 = nextDate($test7);
$nextDate8 = nextDate($test8);
$nextDate9 = nextDate($test9);
$nextDate10 = nextDate($test10);
print($nextDate1->format('m/d/y'));
print('<br />');
print($nextDate2->format('m/d/y'));
print('<br />');
print($nextDate3->format('m/d/y'));
print('<br />');
print($nextDate4->format('m/d/y'));
print('<br />');
print($nextDate5->format('m/d/y'));
print('<br />');
print($nextDate6->format('m/d/y'));
print('<br />');
print($nextDate7->format('m/d/y'));
print('<br />');
print($nextDate8->format('m/d/y'));
print('<br />');
print($nextDate9->format('m/d/y'));
print('<br />');
print($nextDate10->format('m/d/y'));
结果:
05/29/15
05/30/15
05/31/15
06/01/15
06/02/15
06/03/15
06/04/15
01/07/15
01/06/16
05/11/41
修改强>
我已经修改了下面的功能,以找到一周中最接近的一天而不是下一天(虽然除了减去之外它往往与前一个相同)。
function nextDate($date = false){
if(!$date){ $date = new DateTime(); }
$oneYear = new DateInterval('P1Y');
$dayOfWeek = $date->format('w');
$nextDate = clone $date;
$nextDate->add($oneYear);
$nextYearDayOfWeek = $nextDate->format('w');
$diff = $dayOfWeek-$nextYearDayOfWeek;
// if $diff is more than 3, it's faster to go the other way
if(abs($diff) > 3){
if($diff > 0){
$diff = $diff-7;
}else{
$diff = 7+$diff;
}
}
if($diff != 0){
if($diff < 0){
$nextDate->sub(new DateInterval('P'.abs($diff).'D'));
}else{
$nextDate->add(new DateInterval('P'.$diff.'D'));
}
}
return $nextDate;
}
这次测试结果:
05/22/15
05/23/15
05/24/15
05/25/15
05/26/15
05/27/15
05/28/15
12/31/14
12/30/15
05/04/41