【问题标题】:RRULE explanaiton using BYDAY and BYSETPOS使用 BYDAY 和 BYSETPOS 的 RRULE 解释
【发布时间】:2014-07-24 20:57:43
【问题描述】:

我正在尝试解析 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 如何描述一个月的重复发生周数。最终目标是能够解析如上的 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 的语言。即使只是解释 BYSETPOS 和 BYDAY 是如何工作的也很好。

【问题讨论】:

    标签: sql date rrule


    【解决方案1】:

    因此,我遇到的问题是理解 BYSETPOS 如何描述一个月的重复发生周数。

    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 年 7 月,TU、Mo 的设置为:1,2,2,3,3,4,4,5,5 RRULE FREQ=MONTHLY;INTERVAL=1;BYDAY=TU,MO;BYSETPOS=1,2 ,-1,-2 所以 -1 和 -2 将抓住 5,5 说明 TU 和 MO 是该月的第 5 周。但是我仍然看不到它的地方是: RRULE FREQ=MONTHLY;INTERVAL=1;BYDAY=TU,MO;BYSETPOS=1,2,-1,-2 我为该月的第一周和最后一周设置的,这给了我几周的 1,2 和 5,5。
    • 是否使用 2014 年 7 月的 BYSETPOS=1,2,-1,-2 示例编辑了我的回复
    • 我能澄清一下BYDAY=MO;BYSETPOS=-1是否与BYDAY=-1MO相同吗?
    • @u01jmg3 是的,它们完全一样。
    【解决方案2】:

    很好的解释阿诺。帮助我了解它。

    因为对于我自己和其他人来说,这是一个不寻常的概念,所以我复制了我为自己创建的一个 wiki 页面以及我创建的一个简短的 php 脚本,以便通过演示清楚地了解它是如何工作的。

    BYSETPOS 不是规则,而是限制现有规则的东西

    例如,假设您有一个 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

    这到底是什么意思?

    意思是好的,我们知道您的规则将在 7 月 1 日、7 日、8 日、14 日、15 日、21 日、22 日、28 日和 29 日举行活动。但是,我们只想显示事件的第一个、第二个实例 (1,2) 以及最后一个 (-1) 和第二个到最后一个 (-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));
    ?>
    

    【讨论】:

      猜你喜欢
      • 2013-04-01
      • 1970-01-01
      • 2013-01-26
      • 2012-07-24
      • 1970-01-01
      • 1970-01-01
      • 2010-09-11
      • 2019-08-07
      • 2010-11-20
      相关资源
      最近更新 更多