7

私はこれについて少なくとも20のトピックを調べましたが、まだ良い答えは見つかりませんでした。そこで、繰り返しイベントの恐ろしいトピックに関する答えをもう一度尋ねに来ます。

今のところ、Daily、Weekly、Monthly、Yearlyの繰り返しがうまく機能しています(例外イベントなどでシステムを刷新する必要がありますが、当面は機能します)。ただし、毎月、隔月の(1日、2日、3日、4日、5日)[日|月|火|水|木|金|土]にイベントを繰り返す機能を追加できるようにしたいと考えています。そして3ヶ月ごと。

さて、毎月の論理を理解できれば、隔月と3か月ごとに理解できます。

これまでのところ、これが少しです(注:私がそれを行うための最善の方法があると言っているわけではありませんが、システムは、他のプロジェクトで忙しくないときに時間の経過とともに非常にゆっくりと更新されるシステムです。時間があるので、コードをより効率的にします)。

まず、日付計算用にフォーマットされた開始日と終了日を取得します。

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

次に、これら2つの違いを取得して、しばらく前にここで見つけた関数を使用して何回繰り返すかを知り、その量を28日で割って、繰り返す必要のある回数を取得します。月に1つあります:

$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;
}

次に、(1st、2nd、etc ...)の部分を[Sun | Mon | etc ...]の部分に追加して、「最初の日曜日」のようなものを私に与えてくれるものを探していることを理解します。

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

次に、これを繰り返す必要がある回数(上記の$ repeat_number)を実行するループを使用します。

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);
}

今、私はこのコードが機能しないことを知っています、私はかつて繰り返しのために正しい月と年を上げたコードを持っていましたが、必ずしも最初の火曜日またはそれが探していたものを見つけるとは限りませんでした。

誰かが私を正しい方向に向けることができれば、それは最もありがたいです。私はしばらくの間コミュニティに潜んでいて、最近積極的に参加しようとし始めました。

ご意見やアドバイスをよろしくお願いいたします。

4

3 に答える 3

8

これがあなたのための可能な代替案です。 strtotimeは強力であり、構文には、包括的な相対的な時間と日付の表現など、非常に便利なビットが含まれています

「の」の形式を使用して、特定の月の最初からN番目の特定の平日を生成するために使用できます。これは、 DateTimedate_createオブジェクトを呼び出すために使用する例ですが、通常のoldは同じように機能します。strtotime

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

無効なものを要求した場合も、その月はオーバーフローします。

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

序数の表現でのみ機能することに注意してください。残念ながら、「1位」または「3位」を通過することはできません。

これを使用して適切なN番目の平日を取得したら、必要に応じて、指定された終了日または指定された数までスキップする必要のある平日数(1週間は7、2は14、3は21など)を追加できます。数週間が経過しました。もう一度、strtotime救助のために、2番目の引数を使用して相対性を連鎖させます。

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

(私のローカルコピーも受け入れまし'+14 days First Thursday of March 2011'たが、それはちょっと奇妙に感じました。)

于 2011-03-21T17:02:40.590 に答える
3

ハックっぽく見えるかもしれませんが、もっと簡単な方法があります。

私たちにできることは、開始日を取得し、その日の上限を7で割って、開始日から「n」の値を推測することです。

たとえば、開始日が18日である場合、7で割り、上限を使用して、その月の3番目の「何日」であると推測します。

そこから、これに7日を繰り返し追加して新しい日付を取得できます。また、新しい日付の上限が3である場合は常に、その月の次の「n番目の日」に到達します。

いくつかのコードを以下に示します。

$day_nth = ceil(date("j", strtotime($date))/7);
for ($i = 0; $i < $number_of_repeats; $i++) {

    while (ceil(date("j", strtotime($date))/7) != $day_nth)
        $date = date("Y-m-d", strtotime("+7 days", strtotime($date)));

    /* Add your event, or whatever */

    /* Now we increment date by 7 days before the loop starts again,
    ** otherwise the while loop would never execute and we'd just be
    ** adding to the same date repeatedly. */
    $date = date("Y-m-d", strtotime("+7 days", strtotime($date)));
}

この方法の良いところは、どの曜日を扱っているかを気にする必要がないことです。開始日からすべてを推測し、離れて行きます。

于 2014-01-15T19:08:27.710 に答える
0

私はそれをそのようにします:

            //$typeOfDate = 0;
            $typeOfDate = 1;
            $day = strtotime("2013-02-01");
            $to = strtotime(date("Y-m-d", $day) . " +6 month");

            if ($typeOfDate == 0) { //use the same day (number) of the month
                $dateArray[] = date("Y-m-d", $day);
                $event_day_number = date("d", $day);
                while ($day <= $to) {
                    $nextMonth = date("m", get_x_months_to_the_future($day));
                    $day = strtotime(date("Y-" . $nextMonth . "-d", $day));
                    $dateArray[] = date("Y-m-d", $day);
                }
            }

            if ($typeOfDate == 0) { //use the same day (like friday) of the month
                $dateArray[] = date("Y-m-d", $day);
                $monthEvent = date("m", $day);
                $day = strtotime(date("Y-m-d", $day) . " +4 weeks");
                $newMonthEvent = date("m", $day);
                if ($monthEvent == $newMonthEvent) {
                    $day = strtotime(date("Y-m-d", $day) . " +7 days");
                }
                while ($day <= $to) {
                    $dateArray[] = date("Y-m-d", $day);
                    $monthEvent = date("m", $day);
                    $day = strtotime(date("Y-m-d", $day) . " +4 weeks");
                    $newMonthEvent = date("m", $day);
                    if ($monthEvent == $newMonthEvent) {
                        $day = strtotime(date("Y-m-d", $day) . " +7 days");
                    }
                }
            }
于 2013-02-26T22:06:12.117 に答える