DTSTART 和 DTEND 不是 iCalendar RRULE 的一部分,在执行 .toString() 时不应包含在内。
可能会生成类似 "DTSTART=x;DTEND=x;RRULE=x" 的内容,这将是有效的 iCalendar 语法。
还加1这个
同意 - 这在与其他实现(例如_Python dateutil_)互操作时会引起一些麻烦
:+1: 对于这个问题
AFAIK,DTSTART 总是应该是不同的行,而不仅仅是由;
分隔,所以就像 #84 中引用的示例(换行符很重要):
DTSTART;TZID=US-Eastern:19970902T090000
RRULE:FREQ=WEEKLY;INTERVAL=2;UNTIL=19971224T000000Z;WKST=SU;BYDAY=MO,WE,FR
我不认为将这些行与;
连接起来是有效的 RFC 5545(如果错误则等待更正)。
@jkbrzt你接受拉取请求吗?
由于这将是一个重大变化,我可以想象在一个单独的函数中实现它,例如icalString()
并为解析器提供一个选项。
对于遇到此问题的其他任何人,我创建了一个似乎可以满足我需要的辅助函数(注意:它是用打字稿编写的)
export function rrulesetToIcalString(schedule: RRuleSet, startDate: Moment): string {
// matches `;DTSTART=20180125T080000Z` until `;` or end
const icalStrings = schedule.valueOf().map(ruleString => ruleString.replace(/;DTSTART=.*?(?=(?:;)|$)/, ''));
icalStrings.unshift(`DTSTART;TZID=UTC:${startDate.utc().format('YYYYMMDDTHHmmss')}`);
return icalStrings.join('\n');
}
你给它一个RRuleSet
和一个 startDate (我将它设置为与Moment
日期一起使用,但你明白了)它会通过并删除任何;DTSTART=...;
部分RRuleSet。 然后它在 RuleSet 的开头添加一个格式正确的DTSTART
部分,然后将所有部分连接在一起。
注意:我_认为_只假设存在一个DTSTART
值。 然而,也许有一些 iCalendar 风格不是这样的(在我的用例之外)。
要获得兼容的 rrule 字符串(没有 DTSTART),一种选择是直接使用RRule.optionsToString
:
var rule = new RRule({
freq: RRule.WEEKLY,
interval: 5,
byweekday: [RRule.MO, RRule.FR],
dtstart: new Date(2012, 1, 1, 10, 30),
until: new Date(2012, 12, 31)
});
var copy = Object.assign({}, rule.origOptions);
delete copy.dtstart
RRule.optionsToString(copy)
这事有进一步更新吗? 多亏了@phillbaker的建议,获得一个合规的 rrule 字符串并不难,但是能够使用 Python 的 dateutil 即插即用会很好。
同意,RFC 和 Python 在语法上存在一些差异。 对解决这个问题的拉取请求非常开放!
现在TZID
已经实现(#261),库不能再解析它输出的字符串。 我认为通过继续解析 2.4.0 之前的输出字符串,但输出符合 RFC 的字符串,可以实现向后兼容的解决方案。
^ 我在这里的最后一条语句(“库不能再解析它输出的字符串”)现在不正确,这已由 #267 修复。 尽管如此,符合 RFC 还是很理想的!
由 #269 修复
最有用的评论
:+1: 对于这个问题
AFAIK,DTSTART 总是应该是不同的行,而不仅仅是由
;
分隔,所以就像 #84 中引用的示例(换行符很重要):我不认为将这些行与
;
连接起来是有效的 RFC 5545(如果错误则等待更正)。