PHP 5.3重复事件的DateTime [英] PHP 5.3 DateTime for recurring events

查看:112
本文介绍了PHP 5.3重复事件的DateTime的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用较新的PHP DateTime类的日历应用程序。我有办法处理周期性事件,但似乎是黑客,我想看看你们是否有更好的想法:


  1. 我有一个周期性的事件从2009年11月16日开始(2009年11月16日)

  2. 每3天会发生一次

  3. 事件将重现无限期地

让用户查看12月31日的日历 - 此事件应显示每3天像正常情况一样重复。问题是 - 如何计算那个月的日子?



=================== ====================



这是我基本上做的,但我知道我我错过了一些容易的事情:


  1. 我计算出在月初开始的天数差异(12月1日,3100)和事件开始日期(2009年11月16日)存储为$ daysDiff

  2. 我减去模数,以便从开始得到3天的因子:$ daysDiff - ($ daysDiff%3)

  3. 为了论证的缘故让我们以3100年11月29日为日。

  4. 然后添加3天到该日期反复直到我有12月3100之前的所有日期

我的主要问题来自步骤1. PHP DateInterval :: date_diff函数不计算天数差异。它会给我多年,几个月和几天。
11/16/2009 +(1090年* 365.25天)+(9个月* 30.5天)+ 15天



当你像9999年那样走到未来的未来,这个估计可以关闭一个月,那么我必须减去大量的3天的时间间隔才能得到我需要的地方。

解决方案

您可以将日期格式化为unix时间戳,然后使用模块划分在所选月份中查找第一个实例,然后步骤从那里3天的增量。所以例如:

  $ startDate = new DateTime(20091116); 
$ startTimestamp = $ startDate-> format('u');
$ recursEvery = 259200; // 60 * 60 * 24 * 3 = 3天内的秒

//在选定的月份(9月)中找到第一个出现
$ calendarDate = new DateTime(31000901); // init到9月1日,3100
while(0!=(($ calendarDate-> format('u') - $ startTimestamp)%$ recursEvery)){
$ calendarDate-> ('+1天');
}

$ effectiveDates = array();
while($ calendarDate-> format('m')== 9){
$ effectiveDates [] = clone $ calendarDate;
$ calendarDate-> modify('+ 3 day');
}

// $ effectiveDates是3100年9月事件发生的每个日期的数组。

显然,你有一些变量要交换出来,所以用户可以选择任何一个月,但这应该是基本的算法。另外,确保您的DateTimes是正确的日期,但时间设置为00:00:00,否则第一个while循环将永远不会解决。这也假定您确保所选日期晚于事件的开始日期。


I have a calendar application which utilizes the newer PHP DateTime classes. I have a way that I handle recurring events, but it seems hack-ish and I wanted to see if you guys have better ideas:

  1. I have a recurring event that starts 11/16/2009 (Nov 16, 2009)
  2. It will occur every 3 days
  3. The event will recur indefinitely

Let's say the user looks at the calendar for Dec, 3100 - this event should show there repeating every 3 days like normal. The question is - how do I calculate those days in that month?

=========================================

This is how I basically do it, but I know I'm missing something easier:

  1. I calculate the difference in days between the start of the month being looked at (Dec 1, 3100) and the event start date (Nov 16, 2009) stored as $daysDiff
  2. I subtract the modulus, so that I get a factor of 3 days from the start like this: $daysDiff - ($daysDiff % 3)
  3. For the sake of argument lets say that gives me Nov 29, 3100 as a date.
  4. I then add 3 days to that date repeatedly until I have all the dates within Dec 3100

My main problem comes with step 1. The PHP DateInterval::date_diff function does not calculate differences in days. It will give me years, months, and days. I then have to fudge the numbers to get an estimate date around Dec, 3100. 11/16/2009 + (1090 years * 365.25 days) + (9 months * 30.5 days) + 15 days

When you go REAL far into the future like the year 9999, this estimation can be off by a month, then I have to subtract a lot of 3 day intervals to get where I need.

解决方案

You could format your date as a unix timestamp then use modular division to find the first instance in the selected month, then step in increments of 3 days from there. So for your example:

$startDate = new DateTime(20091116);
$startTimestamp = $startDate->format('u');
$recursEvery = 259200; // 60*60*24*3 = seconds in 3 days

// find the first occurrence in the selected month (September)
$calendarDate = new DateTime(31000901); // init to Sept 1, 3100
while (0 != (($calendarDate->format('u') - $startTimestamp) % $recursEvery)) {
    $calendarDate->modify('+1 day');
}

$effectiveDates = array();
while ($calendarDate->format('m') == 9) {
    $effectiveDates[] = clone $calendarDate;
    $calendarDate->modify('+3 day');
}

//$effectiveDates is an array of every date the event occurs in September, 3100.

Obviously, you've got a few variables to swap out so the user can select any month, but that should be the basic algorithm. Also, ensure your DateTimes are the correct date, but with the time set as 00:00:00, or else the first while loop will never resolve. This also assumes you've ensured the selected date is later than the beginning date of the event.

这篇关于PHP 5.3重复事件的DateTime的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆