rrule
版本$ date
)我试图在给定日期(2020 年 2 月 1 日在欧洲/巴黎)之后获得下一个星期二。
尽管如此,如果仍然在那个时区,事件会在星期三开始。
计算时区 America/New_York 的事件符合预期。
请检查以下代码段。 我的发现是:
// problem: events should be on Tuesday but are shifted by one day:
// Tue Feb 04 2020 00:00:00 GMT+0100 (Central European Standard Time) ...
$ TZ=Europe/Paris node zone.js Europe/Paris
rule:
DTSTART;TZID=Europe/Paris:20200131T230000
RRULE:FREQ=WEEKLY;BYDAY=TU;COUNT=2
events:
Wed Feb 05 2020 00:00:00 GMT+0100 (Central European Standard Time)
Wed Feb 12 2020 00:00:00 GMT+0100 (Central European Standard Time)
luxon:
Sat Feb 01 2020 00:00:00 GMT+0100 (Central European Standard Time)
// timezone America/New_York shows correct result
$ TZ=America/New_York node zone.js America/New_York
rule:
DTSTART;TZID=America/New_York:20200201T050000
RRULE:FREQ=WEEKLY;BYDAY=TU;COUNT=2
events:
Tue Feb 04 2020 00:00:00 GMT-0500 (Eastern Standard Time)
Tue Feb 11 2020 00:00:00 GMT-0500 (Eastern Standard Time)
luxon:
Sat Feb 01 2020 00:00:00 GMT-0500 (Eastern Standard Time)
// crossing timezones show correct result
$ TZ=America/New_York node zone.js Europe/Paris
rule:
DTSTART;TZID=Europe/Paris:20200201T050000
RRULE:FREQ=WEEKLY;BYDAY=TU;COUNT=2
events:
Mon Feb 03 2020 18:00:00 GMT-0500 (Eastern Standard Time)
Mon Feb 10 2020 18:00:00 GMT-0500 (Eastern Standard Time)
luxon:
Sat Feb 01 2020 00:00:00 GMT-0500 (Eastern Standard Time)
// UTC shows correct result
$ TZ=UTC node zone.js UTC
rule:
DTSTART:20200201T000000Z
RRULE:FREQ=WEEKLY;BYDAY=TU;COUNT=2
events:
Tue Feb 04 2020 00:00:00 GMT+0000 (Coordinated Universal Time)
Tue Feb 11 2020 00:00:00 GMT+0000 (Coordinated Universal Time)
luxon:
Sat Feb 01 2020 00:00:00 GMT+0000 (Coordinated Universal Time)
const { DateTime } = require('luxon')
const { RRule } = require('rrule/dist/es5/rrule-tz.js')
const dtstart = new Date(2020, 1, 1, 0)
const tzid = process.argv[2] || 'Europe/Paris'
const rule = new RRule({
freq: RRule.WEEKLY,
dtstart,
tzid,
byweekday: [RRule.TU],
count: 2
})
console.log('rule:\n' + rule.toString())
console.log('events:\n' + rule.all().map(d => d.toString()).join('\n'))
const datetime = DateTime.fromJSDate(dtstart).setZone(tzid)
console.log('luxon:\n' + datetime.toJSDate().toString())
你好,同样的问题在这里
重复: "FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR;UNTIL=20200430T040000Z"
rule.all()
显示TU,WE,TH,FR,SA
更新:我认为这纯粹是我对 rrule.js 关于 UTC 输入以及 JS Date 对象的默认行为的困惑。
从其他评论中可以看出,这种混淆似乎很常见:
(1) 使用 TZID
(2)以正确的格式输入DTSTART(时区本地,而不是UTC或计算机本地)
(3) 在rrule.between()
输入正确的日期。 如果声明一个 TZID,就像你必须在日期出现时按摩它们一样 - 使用DateTime.fromJSDate(date).toUTC().setZone('local', { keepLocalTime: true })
,你必须按摩进入between()
(可能是after/before
作为好吧)使用DateTime.fromMillis(posixTime).setZone('utc', { keepLocalTime: true })
。
尽管我在文档方面遇到了麻烦,并且对未记录的行为感到沮丧,但我非常感谢这个库的存在。 感谢创建者和所有维护者和贡献者。 就像luxon
从moment
吸取的教训中成长起来一样,我认为规则库的下一次迭代将建立在rrule.js
的肩膀上。
原始发布的“问题”,请忽略我在下面所说的内容。
也遇到了似乎是这个问题的问题。
import { rrulestr } from 'rrule';
const twoWeeks = 1209600000;
const myrrule = ["DTSTART:20200104T000000Z", "RRULE:FREQ=WEEKLY;BYDAY=FR"]
rrulestr(myrrule.join('\n'))
.between(new Date(Date.now() - twoWeeks), new Date(Date.now() + twoWeeks))
这将返回发生在星期四的日期列表。
我已经确定 DTSTART 是 UTC。
有问题的事件发生在星期五 18:00-0600(山区时间),与星期六 00:00-UTC 相同,但rrule.between()
奇怪地返回时间@星期四 18:00-0600。
我很乐意尝试剖析代码以查看问题发生的位置/方式。 如果任何更熟悉代码库的人有一些提示可以为我指明正确的方向,请告诉我,谢谢!
@davidgoli嘿大卫! 在过去的 5 天里,我一直在使用 rrule,但无法弄清楚如何使用时区。 如果我将时间输入在我的时间晚上 9 点,它会转换为 UTC 时间凌晨 4 点。 当我想在某些日子设置重复事件时,这会导致问题,比如说星期五。 然后它在星期五凌晨 4 点重复,当它被翻译回我的时区时,那么它是星期四晚上 9 点,当我在星期五想要它时。 你对此有什么建议吗? 我尝试过 tzid,但我也无法让它工作。 不确定我应该如何合并 Luxon? 我已经下载了这个包。
最有用的评论
你好,同样的问题在这里
重复:
"FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR;UNTIL=20200430T040000Z"
rule.all()
显示TU,WE,TH,FR,SA