simshaun/recurr

PHP库,用于处理重复规则

v5.0.2 2023-09-26 20:31 UTC

README

tests Latest Stable Version Total Downloads Latest Unstable Version License

Recurr是一个PHP库,用于处理重复规则(RRULE)并将它们转换为DateTime对象。

Recurr是为了开发具有重复事件的日历来开发的,并且受到了rrule.js的极大启发。

安装Recurr

推荐通过 Composer 安装Recurr。

composer require simshaun/recurr

使用Recurr

创建RRULE规则对象

您可以通过传递(RRULE)字符串或包含规则部分的数组、起始日期、结束日期(可选)和时区来创建新的Rule对象。

$timezone    = 'America/New_York';
$startDate   = new \DateTime('2013-06-12 20:00:00', new \DateTimeZone($timezone));
$endDate     = new \DateTime('2013-06-14 20:00:00', new \DateTimeZone($timezone)); // Optional
$rule        = new \Recurr\Rule('FREQ=MONTHLY;COUNT=5', $startDate, $endDate, $timezone);

您还可以使用链式方法来程序化构建您的规则,并获取最终的RRULE。

$rule = (new \Recurr\Rule)
    ->setStartDate($startDate)
    ->setTimezone($timezone)
    ->setFreq('DAILY')
    ->setByDay(['MO', 'TU'])
    ->setUntil(new \DateTime('2017-12-31'))
;

echo $rule->getString(); //FREQ=DAILY;UNTIL=20171231T000000;BYDAY=MO,TU

RRULE到DateTime对象

$transformer = new \Recurr\Transformer\ArrayTransformer();

print_r($transformer->transform($rule));
  1. $transformer->transform(...) 返回一个 RecurrenceCollectionRecurrence 对象。
  2. 每个 Recurrence 都有 getStart()getEnd() 方法,它们返回一个 \DateTime 对象。
  3. 如果转换后的 Rule 缺少结束日期,则 getEnd() 将返回一个与 getStart() 相等的 \DateTime 对象。

注意:转换器有一个“虚拟”限制(默认为732),用于限制它生成的对象数量。这防止了脚本在无限重复的规则上崩溃。您可以通过传递给 ArrayTransformerArrayTransformerConfig 对象来更改虚拟限制。

转换约束

约束用于由ArrayTransformer允许或阻止某些日期被添加到 RecurrenceCollection 中。Recurr提供了以下约束

  • AfterConstraint(\DateTime $after, $inc = false)
  • BeforeConstraint(\DateTime $before, $inc = false)
  • BetweenConstraint(\DateTime $after, \DateTime $before, $inc = false)

$inc 定义了如果 $after$before 本身也是重复项会发生什么。如果 $inc = true,则它们将被包含在集合中。例如,

$startDate   = new \DateTime('2014-06-17 04:00:00');
$rule        = new \Recurr\Rule('FREQ=MONTHLY;COUNT=5', $startDate);
$transformer = new \Recurr\Transformer\ArrayTransformer();

$constraint = new \Recurr\Transformer\Constraint\BeforeConstraint(new \DateTime('2014-08-01 00:00:00'));
print_r($transformer->transform($rule, $constraint));

注意:如果自己构建约束,重要的是要知道不满足约束要求的日子不计算在转换器的虚拟限制之内。如果您手动将约束的 $stopsTransformer 属性设置为 false,转换器可能会通过无限循环崩溃。有关如何防止这种情况的示例,请参阅 BetweenConstraint

转换后 RecurrenceCollection 过滤器

RecurrenceCollection 提供以下链式辅助方法来过滤重复项

  • startsBetween(\DateTime $after, \DateTime $before, $inc = false)
  • startsBefore(\DateTime $before, $inc = false)
  • startsAfter(\DateTime $after, $inc = false)
  • endsBetween(\DateTime $after, \DateTime $before, $inc = false)
  • endsBefore(\DateTime $before, $inc = false)
  • endsAfter(\DateTime $after, $inc = false)

$inc 定义了如果 $after$before 本身也是重复项会发生什么。如果 $inc = true,则它们将被包含在过滤后的集合中。例如,

pseudo...
2014-06-01 startsBetween(2014-06-01, 2014-06-20) // false
2014-06-01 startsBetween(2014-06-01, 2014-06-20, true) // true

注意:RecurrenceCollection 扩展了Doctrine项目中的 ArrayCollection 类。

RRULE到文本

Recurr支持将一些重复规则转换为可读文本。此功能目前处于测试阶段,仅支持年、月、周和日频率。

$rule = new Rule('FREQ=YEARLY;INTERVAL=2;COUNT=3;', new \DateTime());

$textTransformer = new TextTransformer();
echo $textTransformer->transform($rule);

如果您需要除英语以外的语言,可以通过传递一个支持的语言环境(请参阅翻译文件夹)的翻译器。

$rule = new Rule('FREQ=YEARLY;INTERVAL=2;COUNT=3;', new \DateTime());

$textTransformer = new TextTransformer(
    new \Recurr\Transformer\Translator('de')
);
echo $textTransformer->transform($rule);

警告

  • **每月重复规则** 默认情况下,如果您的开始日期在29日、30日或31日,Recurr将跳过那些天数不足的月份。(例如:1月31日 + 1个月 = 3月)

此行为是可以配置的

$timezone    = 'America/New_York';
$startDate   = new \DateTime('2013-01-31 20:00:00', new \DateTimeZone($timezone));
$rule        = new \Recurr\Rule('FREQ=MONTHLY;COUNT=5', $startDate, null, $timezone);
$transformer = new \Recurr\Transformer\ArrayTransformer();

$transformerConfig = new \Recurr\Transformer\ArrayTransformerConfig();
$transformerConfig->enableLastDayOfMonthFix();
$transformer->setConfig($transformerConfig);

print_r($transformer->transform($rule));
// 2013-01-31, 2013-02-28, 2013-03-31, 2013-04-30, 2013-05-31

贡献

欢迎评论或发起拉取请求。请将测试与PR一起包括在内。

许可证

Recurr遵循MIT许可证。有关详细信息,请参阅LICENSE文件。