[英]PHP get same day of same week next year
我正在研究客户调度程序,我的雇主希望它每年自动重新安排客户。 他希望他们每年保持同一周的同一天。
例如,客户定于2014年5月23日。这是5月的第四个周五。 2014年5月23日过后,应预订2015年5月4日的预约(在本案例中为第22次)。
我已经尝试了各种各样的工作来使这个工作(例如使用DateTime提前一年,并找到一周中任何一天的“之前”)。 但是,我尝试过的每一款车型在短短几年后都会出现故障。 他们最终会像......这个月的第二个星期五。
有没有人有办法让这个工作? 我的雇主非常具体地希望调度程序以这种方式工作。 xx如果有人知道如何,我真的很感激帮助。
感谢您阅读本文!
正如已经指出的那样,例如,可能没有6月的第5个星期五,所以需要一些标准的方法来决定明年哪一周与当前星期相同。
实际上, ISO 8601中已有一个用于周编号的标准 ,PHP的DateTime类内置了处理它们的功能。
我的建议是安排同一天的下一次会议在同一年的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'));
}
我相信你会同意这是最简单的方法,它会让你在接下来的100年或更长时间内正确行事:)
我认为这将满足您的需求。 不过,你需要彻底测试它才能确定。
$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');
因此,将您的要求更改为“添加一年并找到一周的下一个匹配日期”,我想出了这个:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.