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
보μ¬μ€λλ€.
μ λ°μ΄νΈ: λλ μ΄κ²μ΄ μμ ν UTC μ λ ₯ λ° JS Date κ°μ²΄μ κ΄ν rrule.jsμ κΈ°λ³Έ λμμ λν λ΄ νΌλμ΄λΌκ³ μκ°ν©λλ€.
λ€λ₯Έ μ견μμ μ μ μλ―μ΄ μ΄ νΌλμ λ§€μ° νν κ² κ°μ΅λλ€.
(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
μμ λ°°μ΄ κ΅νμ λ°νμΌλ‘ μ±μ₯ν κ²μ²λΌ λ€μ rule λΌμ΄λΈλ¬λ¦¬ λ°λ³΅μ 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
보μ¬μ€λλ€.