2

RRULE を解析して、繰り返しイベントが有効な月の週を表示しようとしています。RFC2445 ドキュメント ( http://www.ietf.org/rfc/rfc2445.txt ) を見ましたが、それほど明確ではありません。

たとえば、次のルールを知っています。

RRULE FREQ=MONTHLY;INTERVAL=1;BYDAY=TH,FR,WE;BYSETPOS=10,11,12,7,8,9,1,2,3,4,5,6

毎月第1、第2、第3、第4週の水、木、金曜日です。

また

RRULE FREQ=MONTHLY;INTERVAL=1;BYDAY=TU,MO;BYSETPOS=3,4,5,6;

月の第 2 週と第 3 週の月曜日と火曜日です。

また

RRULE FREQ=MONTHLY;INTERVAL=1;BYDAY=TH,WE;BYSETPOS=-1,-2

月の最終週の水曜日と木曜日です。

これらを別のプログラムで生成しましたが、実際にどのように生成したかはわかりません。

したがって、私が抱えている問題は、BYSETPOS が 1 か月の再発週をどのように記述するかを理解することです。最終的な目標は、上記のような RRULE を解析して次のように表示できるようにすることです。

為に: RRULE FREQ=MONTHLY;INTERVAL=1;BYDAY=TH,FR,WE;BYSETPOS=10,11,12,7,8,9,1,2,3,4,5,6

見せる:Thur,Friday,Wed on week:1,2,3,4

為に: RRULE FREQ=MONTHLY;INTERVAL=1;BYDAY=TU,MO;BYSETPOS=3,4,5,6;

見せる:Tues, Monday on week:2,3

為に: RRULE FREQ=MONTHLY;INTERVAL=1;BYDAY=TH,WE;BYSETPOS=-1,-2

見せる:Whu,Wed on last week

最善の解決策は、objective-c の文字列ですが、それが別の C のような言語であるかどうかはわかります。BYDAY を使用した BYSETPOS がどのように機能するかの説明だけでも素晴らしいでしょう。

4

2 に答える 2

8

したがって、私が抱えている問題は、BYSETPOS が 1 か月の再発週をどのように記述するかを理解することです。

BYSETPOS は週を表すのではなく、残りのルールに対応するインスタンスを計算した後の単に n 番目のインスタンスを表します。たとえばFREQ=MONTHLY;INTERVAL=1;BYDAY=TU,MO、毎月の月曜日と火曜日に対応します。したがって、各月について、最初にセットを計算します (たとえば、2014 年 7 月の場合は 9 つのエントリ)。次に、BYSETPOS は、保持する必要があるセットへの「インデックス」を提供します。-1、-2 は、セットへの最後の 2 つのエントリを意味します。

2014 年 7 月の例を続けると、基本ルールは次のセットを返します: (7 月 1 日、7 日、8 日、14 日、15 日、21 日、22 日、28 日、29 日)。BYSETPOS=1,2,-1,-2 の場合、7 月 1 日、7 日、28 日、29 日を保持します。

https://www.rfc-editor.org/rfc/rfc5545を参照してください。これは RFC2245 を廃止し、繰り返しルールの詳細な説明があります。

于 2014-07-25T08:08:32.303 に答える
0

良い説明アルノー。自分の頭を理解するのに役立ちました。

これは私自身や他の人が理解するのが非常に珍しい概念であるため、私が作成した短い php スクリプトと一緒に自分用に作成した wiki ページをコピーして、デモによってどのように動作するかを明確に理解できるようにしました。

BYSETPOSはルールではなく、既存の rrule を制限するものです

たとえば、次のように月に 2 回、月と火に永久に発生するイベントの RRULE があるとします。

FREQ=MONTHLY;INTERVAL=1;BYDAY=MO,TU

ここで、上記の Arnaud の例を取り上げ、例として 7 月のみに注目してみましょう。

7 月 1 日が最初の水曜 7 月 7 日が次の火曜、8 日が次の水曜、というように続きます。上記の RRULE では、7 月 1 日、7 日、8 日、14 日、15 日、21 日、22 日、28 日、29 日にイベントが発生します。次に、BYSETPOS リミッターを追加します。

FREQ=MONTHLY;INTERVAL=1;BYDAY=MO,TU; BYSETPOS=1,2,-1,-2

これは正確には何を言っているのですか?

OK と言っています。あなたのルールでは、7 月 1 日、7 日、8 日、14 日、15 日、21 日、22 日、28 日、29 日にイベントが開催されることがわかっています。ただし、イベントの 1 番目と 2 番目のインスタンス (1,2) と、最後のインスタンス (-1) と 2 番目から最後のインスタンス (-2) のみを表示する必要があります。

BYSETPOS は、BYSETPOS リミッターにあるインスタンスのみを表示するように指示します。

したがって、日の配列 $moDays Array(1,7,8,14,15,21,22,28,29) を取得し、BYSETPOS リミッター $bspLimiter=Array(1,2,-1,- 2) 次のようになります。

<?php
// 9 event days - limiting the events displayed based on the BYSETPOS limiter

$moDays = array(1,7,8,14,15,21,22,28,29);
$bspLimiter = array(1,2,-1,-2);
$keepers = [];
for($b=0;$b<count($bspLimiter);$b++){
    if($bspLimiter[$b] < 0){
        echo '$bspLimiter[$b] is negative value ('.$bspLimiter[$b].') so getting from back of array<br>';
        $limiter=count($moDays)+$bspLimiter[$b];
        $keeper=$moDays[$limiter];
        $keepers[]=$keeper;
    } else {
        # accounting for index
        $limiter = $bspLimiter[$b]-1;
        $keeper=$moDays[$limiter];
        $keepers[]=$keeper;
    }

    echo '<b>keeping '.$keeper."</b><Br>";

}
echo "<hr>";
asort($keepers);
echo $keepers=str_replace("'","",implode("', '", $keepers));
?>
于 2020-01-19T21:29:29.677 に答える