繁体   English   中英

PHP获得明年同一周的同一天

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM