【问题标题】:Add multiple of interval to date until date is in current year添加多个间隔到日期,直到日期在当年
【发布时间】:2014-10-21 18:07:01
【问题描述】:

假设我有一个初始日期,其年份早于当年,我想每 7 天重复一次该事件,但仅限于当年。

如何找到当年的第一次出现?

我意识到我可以用这样的循环来做到这一点:

$reOccurringEvent =new DateTime('2013-12-01');
$interval = new DateInterval('P7D');
while($reOccurringEvent->format('Y') < date('Y') ){
    $reOccurringEvent->add($interval);
}
echo $reOccurringEvent->format('d m Y'); //05 01 2014

但令我震惊的是,应该有一种更有效的方法来实现这一点,而不是重复地在日期上添加一个间隔(如果初始日期是几年前,它会发生很多次)。

我希望能够计算应该添加间隔的次数,并且只执行一次。

我在想这样的事情:

$date = new DateTime();
$diff = $date->diff($reOccurringEvent)->days%7;

但显然这行不通,我无法完全弄清楚如何做到这一点的逻辑。

【问题讨论】:

    标签: php date


    【解决方案1】:

    更一般地说,该算法将查找给定日期和去年最后一天之间的间隔数。然后将区间乘以区间数+1,得到当前年份的第一个区间。

    $date1="12/9/2013"; 
    $ts1 = strtotime($date1);
    $ts2 = strtotime("12/31/" . Date("Y")-1);
    
    //get the number of seconds between the date and first of the year    
    $seconds_diff = $ts2 - $ts1;
    echo "$seconds_diff <br>";
    
    //get the number of days
    $dayDiff=$seconds_diff/86400;
    
    //how many intervals?
    $intervalDays = "10";
    
    //get the number of intervals from start date to last day of last year
    $numIntervals = floor($dayDiff/$intervalDays);
    echo  $numIntervals."<br>";
    
    //now the total intervals to get into the current year is one more interval, turn this into days
    $totIntervals= ($numIntervals* $intervalDays)+$intervalDays;
    
    //Date Time date in question
    $theDt = new DateTime($date1);
    
    //Add the intervals we calculated to the date in question, and we have the first date of the interval for the current year...
    $theDt->add(new DateInterval('P' . $totIntervals. 'D'));
    
    echo "The first date of the intreval is: " . $theDt->format('Y-m-d'); 
    

    【讨论】:

    • 谢谢,我稍微修改了一下,(见我的回答)但效果很好
    【解决方案2】:

    我认为,如果您以 7 天为间隔,您可以找出初始日期的星期几,然后用该星期几获得当年的第一个日期......

    找出星期几:How to find the day of week from a date using PHP?

    找出今年星期几的日期:Getting first weekday in a month with strtotime

    把它放在一起:

    $date=Date("2/8/2012");
    
    //Get the day of week for the date in question
    $dayOfWeek  = date('l', strtotime($date));
    echo "The day of week for the given date is: $dayOfWeek <br>"; 
    
    //Get the current year
    $thisYear = date("Y");
    echo "This year: $thisYear <br>"; 
    
    //Create a date with the first occurence of the day of week of the given date for the current year
    $firstOccurenceThisYear = date("m/d/y", strtotime("January " .$thisYear ." " . $dayOfWeek));
    echo "The first interval of the year is: $firstOccurenceThisYear"; 
    
    /*
    Output:
    This year: 2014 
    The day of week for the given date is: Wednesday 
    The first interval of the year is: 01/01/14
    */
    

    【讨论】:

    • 您提出的第一种方法的问题是 catch 22,我不知道第二个日期来进行比较,即我要计算的日期:) 第二种方法看起来很有希望,我会报告的
    • 谢谢,当期限不是 7 天时,我仍然需要想办法做到这一点,但我可能应该在问题中指定:)
    • @andrew 发布了我认为更通用地解决问题的新答案
    【解决方案3】:

    这是@Dan 的第二个答案的略微修改版本,对我来说效果很好。

    如下所示的基准。

    $date="1985-02-18";
    $intervalDays = "5";
    
    //original version
    $benchMark = microtime(true);
    $dt1 = new DateTime($date);
    $interval = new DateInterval("P{$intervalDays}D");
    while ($dt1->format('Y') < date('Y')) {
        $dt1->add($interval);
    }
    echo $dt1->format('d m Y') . '<br>';
    echo microtime(true)-$benchMark.'<br>';
    
    
    //new version
    $benchMark = microtime(true);
    $dt1 = new DateTime($date);
    $dt2 = new DateTime("12/31/" . ((int) Date("Y") - 1));
    $dayDiff = $dt1->diff($dt2)->days;
    $numIntervals = floor($dayDiff / $intervalDays);
    $totIntervals = ($numIntervals * $intervalDays) + $intervalDays;
    $dt1->add(new DateInterval('P' . $totIntervals . 'D'));
    echo $dt1->format('d m Y').'<br>';
    echo microtime(true)-$benchMark.'<br>';
    exit;
    

    输出

    02 01 2014
    0.0145111083984
    02 01 2014
    0.000123977661133
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-01
      相关资源
      最近更新 更多