在“第n个”上重复事件每个月的平日 [英] Repeating Events on the "nth" Weekday of Every Month

查看:170
本文介绍了在“第n个”上重复事件每个月的平日的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看过至少二十几个关于这个的话题,还没有真正找到一个很好的答案,所以我再来询问一下关于重复事件可怕话题的答案。



我现在有每日,每周,每月和每年重复工作(我仍然需要使用异常事件来改造系统,但现在还是有效的) 。但是,我们希望能够在每个月的每一个月(一,二,三,四,五)[太阳|周一|周二|周三|周四|周五|周六]上增加重复活动的能力,每三个月一次。



现在,如果我能够理解每个月的逻辑,我可以找出每隔一个月和每三个月。 p>

这里有一些我到目前为止(注意:我不是说我有最好的办法或任何事情,但系统是我们更新非常缓慢随着时间的推移,当我们不忙于其他项目,所以我使代码更有效率,因为我有时间)。



首先我得到开始和结束日期格式化日期计算:

  $ ending = $ _POST ['end_month']。 /。 $ _POST ['end_day']。 /。 substr($ _ POST ['end_year'],2,2); 
$ starting = $ _POST ['month']。 /。 $ _POST ['day']。 /。 substr($ _ POST ['year'],2,2);

然后我得到这两个之间的区别,知道重复使用一个函数多少次相当肯定的是,我之前在这里发现了这个数量,并将这个数量除以28天才能得到需要重复的TIMES数量,以便每月有一个:

  $ repeat_number = date_diff($ starting,$ ending)/ 28; 
//找到两个日期之间的DAYS差异
function date_diff($ old_date,$ new_date){
$ offset = strtotime($ new_date) - strtotime($ old_date);
返回$ offset / 60/60/24;
}

然后我将(第1,第2等等)部分添加到[Sun | Mon | etc ...]部分来弄清楚他们正在寻找什么让我像第一个星期天一样:

  $ find = $ _POST ['custom_number']。 。 $ _POST ['custom_day']; 

然后我使用一个循环来运行这个需要重复的次数(上面的$ repeat_number ($ m = 0; $ m <= $ repeat_number; $ m ++){
if ($ m == 0){
$ month = date('F',substr($ starting,0,2));
} else {
$ month = date('F',strtotime($ month。'+'。$ m。'months'));
}
$ repeat_date = strtotime($ find。'in'。$ month);
}

现在,我知道这段代码不行,我在一个时间确实有代码重新出现正确的月份和年份,但不一定会找到第一个星期二或任何正在寻找的内容。



如果有人能指出我正确的方向,那将是最受赞赏的。我一直在社区潜伏一段时间,刚刚开始试图积极参与。



提前感谢您提供的任何投入或建议。 p>

解决方案

这是一个可能的选择。 strtotime 功能强大,语法包括真正有用的位,如全面的相关时间和日期措辞



您可以使用它来生成第一到第N个特定使用格式of的特定月份的平日。以下是使用 date_create 的示例调用 DateTime 对象,但常规旧的 strtotime 的工作方式相同:

  php> $ d = date_create(2011年3月上旬); if($ d instanceof DateTime)echo $ d-> format('l F d Y H:i:s'); 
2011年3月25日星期五00:00:00
php> $ d = date_create(2011年3月第一个星期五); if($ d instanceof DateTime)echo $ d-> format('l F d Y H:i:s');
2011年3月4日星期五00:00:00
php> $ d = date_create(2011年3月第一个星期日); if($ d instanceof DateTime)echo $ d-> format('l F d Y H:i:s');
2011年3月6日星期三00:00:00
php> $ d = date_create(2011年3月第四个星期日); if($ d instanceof DateTime)echo $ d-> format('l F d Y H:i:s');
2011年3月27日星期三00:00:00
php> $ d = date_create(2011年3月最后一个星期日); if($ d instanceof DateTime)echo $ d-> format('l F d Y H:i:s');
2011年3月27日星期三00:00:00

它也会溢出月份,如果你要求一个无效的:

  php> $ d = date_create(2011年3月9日星期日); if($ d instanceof DateTime)echo $ d-> format('l F d Y H:i:s'); 
2011年5月1日星期日00:00:00

请注意,它只适用于<一个href =http://en.wikipedia.org/wiki/English_numerals#Ordinal_numbers>序数措辞。不幸的是,你不能通过第一或第三。



一旦你使用它来抓住正确的第N个工作日,你可以简单地添加所需的数量工作日要跳过(7周一周,14次,2次,21次,3次等),直到指定的结束日期或指定的周数过去。再次, strtotime 来拯救,使用第二个参数链接相关性:

  php>回覆日期('l F d Y H:i:s',strtotime('+ 14 days',strtotime('2011年3月的第一个星期四))); 
2011年3月17日星期三00:00:00

(我的本地副本也接受'+ 14天2011年3月的第一个星期四',但这感觉很奇怪。)


I've looked at at least 2 dozen topics about this and haven't really found a good answer yet, so I come to you to ask once again for answers regarding the dreaded topic of Repeating Events.

I've got Daily, Weekly, Monthly, and Yearly repeats working out fine for now (I still need to revamp the system with Exception events and whatnot, but it works for the time being). But, we want to be able to add the ability to repeat events on the (1st,2nd,3rd,4th,5th) [Sun|Mon|Tue|Wed|Thu|Fri|Sat] of every month, every other month, and every three months.

Now, if I can just understand the logic for the every month, I can figure out the every other month and the every three months.

Here's a bit of what I have so far (note: I'm not saying I have the best way of doing it or anything, but the system is one we update very slowly over time when we aren't busy with other projects, so I make the code more efficient as I have the time).

First I get the starting and ending dates formatted for date calculations:

$ending = $_POST['end_month'] . "/" . $_POST['end_day'] . "/" . substr($_POST['end_year'], 2, 2);
$starting = $_POST['month'] . "/" . $_POST['day'] . "/" . substr($_POST['year'], 2, 2);

Then I get the difference between those two to know how many times to repeat using a function I'm fairly certain I found on here some time ago and dividing that amount by 28 days to get just about how many TIMES it needs to repeat so that there is one a month:

$repeat_number = date_diff($starting, $ending) / 28;
//find the difference in DAYS between the two dates
function date_diff($old_date, $new_date) {
$offset = strtotime($new_date) - strtotime($old_date);
return $offset/60/60/24;
}

Then I add the (1st,2nd,etc...) part to the [Sun|Mon|etc...] part to figure out what they are looking for giving me somehthing like 'first Sunday' :

$find = $_POST['custom_number']. ' ' . $_POST['custom_day'];

Then I use a loop that runs the number of times this needs to repeat (the $repeat_number from above):

for($m = 0; $m <= $repeat_number; $m++) {
if($m == 0) {
     $month = date('F', substr($starting,0,2));
} else {
     $month = date('F', strtotime($month . ' + ' . $m . ' months'));
}
$repeat_date = strtotime($find . ' in ' . $month);
}

Now, I'm aware this code doesn't work, I at one time did have code that turned up the correct month and year for the repeat, but wouldn't necessarily find the first tuesday or whatever it was that was being looked for.

If anyone could point me back in the right direction, it would be most appreciated. I've been lurking in the community for some time now, just started trying to actively participate recently.

Thanks in advance for any input or advice you can provide.

解决方案

Here's a possible alternative for you. strtotime is powerful, and the syntax includes really useful bits like comprehensive relative time and date wording.

You can use it to generate the first through Nth specific weekdays of a specific month by using the format " of ". Here's an example using date_create to invoke a DateTime object, but regular old strtotime works the same way:

php > $d = date_create('Last Friday of March 2011'); if($d instanceof DateTime) echo $d->format('l F d Y H:i:s');
Friday March 25 2011 00:00:00
php > $d = date_create('First Friday of March 2011'); if($d instanceof DateTime) echo $d->format('l F d Y H:i:s');
Friday March 04 2011 00:00:00
php > $d = date_create('First Sunday of March 2011'); if($d instanceof DateTime) echo $d->format('l F d Y H:i:s');
Sunday March 06 2011 00:00:00
php > $d = date_create('Fourth Sunday of March 2011'); if($d instanceof DateTime) echo $d->format('l F d Y H:i:s');
Sunday March 27 2011 00:00:00
php > $d = date_create('Last Sunday of March 2011'); if($d instanceof DateTime) echo $d->format('l F d Y H:i:s');
Sunday March 27 2011 00:00:00

It will also overflow the month, if you ask for an invalid one:

php > $d = date_create('Ninth Sunday of March 2011'); if($d instanceof DateTime) echo $d->format('l F d Y H:i:s');
Sunday May 01 2011 00:00:00

Note that it only works with the ordinal number wording. You can't pass "1st" or "3rd", unfortunately.

Once you use this to grab the proper Nth weekday, you can then simply add the number of needed weekdays to skip (7 for one week, 14 for two, 21 for three, etc) as required until the designated end date or designated number of weeks has passed. Once again, strtotime to the rescue, using the second argument to chain together relativeness:

php > echo date('l F d Y H:i:s', strtotime('+14 days', strtotime('First Thursday of March 2011')));
Thursday March 17 2011 00:00:00

(My local copy also accepted '+14 days First Thursday of March 2011', but that felt kind of weird.)

这篇关于在“第n个”上重复事件每个月的平日的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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