3

現在、カレンダー アプリで毎日または毎週の繰り返しイベントを許可しています (fullCalendar を使用)。

私のビューには、2 つのドロップダウンを有効にするチェックボックスがあります。1 つは繰り返し間隔 (毎日、毎週) 用で、もう 1 つは頻度 (1 回、2 回など) 用です。

$evt_interval_options = array( //this will be $row->interval in the model
    '86400' => 'Daily',   
    '604800' => 'Weekly'; 

$evt_frequency_options = array(  //this will be //$i in the model
    '1' => '2',    
    '2' => '3',    

<?php echo form_checkbox('evt_repeat', 'FALSE', FALSE, 'class="repeat_checkbox"'); 
      echo form_dropdown('evt_interval', $evt_interval_options');
      echo form_dropdown('evt_frequency', $evt_frequency_options'); ?>

これは最終的に私のモデルに到達し、イベントを繰り返す必要があるかどうかを確認するループを実行します。繰り返す場合は、間隔 ( $row->interval) と頻度 ( $i) を考慮に入れます。

$cal_data[] = array(
    'start' => strtotime($row->date_1 . ' ' . $row->time_1) + ($i ? ($row->interval * $i) : 0),
);

これは、データベース内の単一のレコード エントリに基づいて、毎日または毎週の複数のイベントを表示するのにうまく機能します。

問題は月次と年次です。これらの秒数は可変であるため、

03/01/2011 00:00:00 --> 04/01/2011 00:00:00 ===> 2674800 seconds
04/01/2011 00:00:00 --> 05/01/2011 00:00:00 ===> 2592000 seconds
and so on for monthly and yearly differences

では、この問題を解決するにはどうすればよいですか? たとえば、月次を繰り返す必要があること、または年次を繰り返すstrtotime必要があることを正確に示すのに役立つ関数またはコマンドはありますか?4thJuly 4th

PHP 5.2.14 を使用しています。

4

4 に答える 4

5

答えてくれてありがとう - strtotime()の PHP.net マニュアルから@akniepがこの関数で問題を解決しました。

function get_x_months_to_the_future( $base_time = null, $months = 1 )
{
    if (is_null($base_time))
        $base_time = time();

    $x_months_to_the_future    = strtotime( "+" . $months . " months", $base_time );

    $month_before              = (int) date( "m", $base_time ) + 12 * (int) date( "Y", $base_time );
    $month_after               = (int) date( "m", $x_months_to_the_future ) + 12 * (int) date( "Y", $x_months_to_the_future );

    if ($month_after > $months + $month_before)
        $x_months_to_the_future = strtotime( date("Ym01His", $x_months_to_the_future) . " -1 day" );

    return $x_months_to_the_future;
}

これが何をするかは、日29, 30, 31と月に繰り返される月次イベントの問題を解決することFeb 28です。

カレンダー アプリの POV から私の問題を解決してくれるので、この機能が気に入っています。

Jan 31ユーザーが通常から始まる毎月の定期的なイベントを要求した場合、strtotime2 月と 31 日を含まない他の月の間は不規則に動作します。

上記のコメントで指摘したように、Google カレンダーは、そのような日付がない月をスキップすることで、この問題をいくぶん奇妙に解決します。

好みの問題だと思いますが、定期的なイベントを月の最終日に配置することを提案する方が理にかなっています。そのため、このJan 31例では、定期的なイベントが発生しFeb 28 Mar 31 Apr 30ます。

この関数をループに配置し、ユーザーが要求する回数だけ繰り返すと、完全に機能します。また、年次イベントでもうまく機能します。そのため12、月数として渡すだけです。

于 2011-05-10T02:54:05.740 に答える
3

DateTimePHPのクラスでうまくいくようです

$dt = new DateTime('3rd Jan 2011');
echo $dt->format('r') . PHP_EOL;

$dt->modify('+1 year');
echo $dt->format('r') . PHP_EOL;

編集: 29,30,31 については、現在の月に表示されない可能性があるため、毎月の繰り返しを処理する方法について特別な考慮を払う必要があります。予期しない出力の例を次に示します。

$dt = new DateTime('29 Jan 2011');
echo $dt->format('r') . PHP_EOL;

$dt->modify('+1 month');
echo $dt->format('r') . PHP_EOL;
于 2011-05-09T20:31:26.747 に答える
2
$evt_interval_options = array( //this will be $row->interval in the model
    '86400' => 'Daily',   
    '604800' => 'Weekly';

精度を確保したい場合は、秒数を使用しないでください。時間枠に DST の変更がある場合、問題が発生し、計算が正確ではなくなります。また、すべての月が同じ日数を持っているわけではないため、秒を使用して数え続けることはできません。

PHP DateTime クラスおよび/または を使用することをお勧めしますstrtotime。後者は平易な英語で日付を理解し、strtotime('seconds monday of next month');6 月 13 日のタイムスタンプを返します。

于 2011-05-09T20:39:08.633 に答える
1

strtotime は、「今日、翌月」や「2011-05-09 来週」など、驚くべきことを実行できます。これらを使用して、基本的な日付調整を行うことができます。ただし、カレンダー型の状況ではこれを適切に処理できません。「2011-01-30 来月」と言うと、2 月 30 日ではなく、3 月 1 日または 2 日になります (閏年によって異なります)。

日付を個々の y/m/d/h/m/s コンポーネントに分解し、繰り返しコンポーネントを調整してから mktime() で再組み立てする必要があるかもしれませんが、これでも悪い日付を同等の通常のものに修正します。つまり、「調整後」の日付を検証して、それらが目的に対して有効であることを確認する必要があります。

于 2011-05-09T20:28:19.280 に答える