af/rrule

处理重复规则的 PHP 库

dev-master / 1.0.x-dev 2015-08-25 11:33 UTC

This package is not auto-updated.

Last update: 2024-10-02 09:54:16 UTC


README

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

Recurr 是作为一个具有重复事件的日历的先驱开发的,并且深受 rrule.js 的启发。

安装

Recurr 存储在 Packagist 上,这意味着您可以使用 Composer 安装它

composer require af/rrule:~1.0

或添加

"af/rrule" : "~1.0"

到您的应用程序 composer.json 文件的 require 部分。

RRULE 到 DateTime 对象

$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);
$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),限制了它生成的对象数量。这防止了脚本在无限重复的规则上崩溃。您可以在调用 transformArrayTransformer 构造函数时更改虚拟限制。

转换约束

约束(\Recurr\Transformer\ConstraintInterface)由 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, null, $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);

如果您需要除英语以外的语言,可以传递一个带有支持的区域设置(目前为 en、de、fr、it)的翻译器。

$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将跳过那些天数少于该数字的月份。
$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));

/* Recurrences:
 * 2013-01-31
 * 2013-02-28
 * 2013-03-31
 * 2013-04-30
 * 2013-05-31
 */

贡献

Recurr仍在beta测试阶段,很可能存在100%的bug。请随意评论或提交pull requests。请将测试与PR一起提交。

许可证

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