Rrule: TZIDκ°€ μžˆλŠ” DTSTART: 사이에 잘λͺ»λœ μ‹œκ°„μ΄ 생성됨

에 λ§Œλ“  2019λ…„ 07μ›” 16일  Β·  16μ½”λ©˜νŠΈ  Β·  좜처: jakubroztocil/rrule

문제 보고

const ruleStr = [
'DTSTART;TZID=America/Los_Angeles:20190603T181500', 
'RRULE:FREQ=WEEKLY;WKST=SU;BYDAY=MO,TU,WE,FR,SA'
].join('\n')
const rule = RRule.fromString(ruleStr)
const result = rule.between(
new Date('2019-07-16T07:00:00.000-07:00'), 
new Date('2019-07-23T07:00:00.000-07:00')
)
console.log(result)

λ‹€μŒμ„ 좜λ ₯ν•©λ‹ˆλ‹€.

0:Tue Jul 16 2019 15:15:00 GMT-0500 (CDT) {}
1:Wed Jul 17 2019 15:15:00 GMT-0500 (CDT) {}
2:Fri Jul 19 2019 15:15:00 GMT-0500 (CDT) {}
3:Sat Jul 20 2019 15:15:00 GMT-0500 (CDT) {}
4:Mon Jul 22 2019 15:15:00 GMT-0500 (CDT) {}

15:15:00 GMT-0500 (CDT) λŠ” 17:15 PDT이고 DTSTARTλŠ” DTSTART;TZID=America/Los_Angeles:20190603T181500

@davidgoli에 μ˜ν•΄ κ΅¬ν˜„λœ tzid μ„€μ •ν•˜λ©΄ λ‹€λ₯Έ κ²°κ³Όκ°€ λ‚˜νƒ€λ‚©λ‹ˆλ‹€.

const ruleStr = [
'DTSTART:20190603T181500', 
'RRULE:FREQ=WEEKLY;WKST=SU;BYDAY=MO,TU,WE,FR,SA'
].join('\n')
const rule = RRule.fromString(ruleStr)
const ruleSet = new RRuleSet()
ruleSet.rrule(rule)
ruleSet.tzid('America/Los_Angeles')
const result = ruleSet.between(
new Date('2019-07-16T07:00:00.000-07:00'), 
new Date('2019-07-23T07:00:00.000-07:00')
)
console.log(result)
0:Tue Jul 16 2019 13:15:00 GMT-0500 (CDT) {}
1:Wed Jul 17 2019 13:15:00 GMT-0500 (CDT) {}
2:Fri Jul 19 2019 13:15:00 GMT-0500 (CDT) {}
3:Sat Jul 20 2019 13:15:00 GMT-0500 (CDT) {}
4:Mon Jul 22 2019 13:15:00 GMT-0500 (CDT) {}

μ˜ˆμƒ κ²°κ³ΌλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

0:Tue Jul 16 2019 20:15:00 GMT-0500 (CDT) {}
1:Wed Jul 17 2019 20:15:00 GMT-0500 (CDT) {}
2:Fri Jul 19 2019 20:15:00 GMT-0500 (CDT) {}
3:Sat Jul 20 2019 20:15:00 GMT-0500 (CDT) {}
4:Mon Jul 22 2019 20:15:00 GMT-0500 (CDT) {}

κ·Έ μ΄μœ λŠ” λ¬΄μ—‡μž…λ‹ˆκΉŒ?
κ·œμΉ™ 버전: 2.6.2
CDT μ‹œκ°„λŒ€μ—μ„œ λ…Έλ“œλ₯Ό μ‹€ν–‰ν•©λ‹ˆλ‹€. λ‚΄ μ‹œμŠ€ν…œ μ‹œκ°„λŒ€λŠ” America/Los_Angeles

λͺ¨λ“  16 λŒ“κΈ€

이 μ €μž₯μ†Œλ₯Ό λ³΅μ œν•˜κ³  λ‹€μŒ ν…ŒμŠ€νŠΈλ₯Ό μΆ”κ°€ν–ˆμŠ΅λ‹ˆλ‹€.

  it('generates correct recurrences when recurrence is WEEKLY and has BYDAY specified', () => {
    const rrule = new RRule({
      freq: RRule.WEEKLY,
      dtstart: new Date(Date.UTC(2019, 6, 17, 18, 0, 0)),
      tzid: 'America/Los_Angeles',
      count: 10,
      interval: 1,
      wkst: RRule.SU,
      byweekday: [RRule.MO, RRule.TU, RRule.WE, RRule.FR, RRule.SA]
    })

    expect(rrule.all()).to.deep.equal([
      new Date('2019-07-17T18:00:00.000-07:00'), // WE
      new Date('2019-07-19T18:00:00.000-07:00'), // FR
      new Date('2019-07-20T18:00:00.000-07:00'), // SA
      new Date('2019-07-22T18:00:00.000-07:00'), // MO
      new Date('2019-07-23T18:00:00.000-07:00'), // TU
      new Date('2019-07-24T18:00:00.000-07:00'),
      new Date('2019-07-26T18:00:00.000-07:00'),
      new Date('2019-07-27T18:00:00.000-07:00'),
      new Date('2019-07-29T18:00:00.000-07:00'),
      new Date('2019-07-30T18:00:00.000-07:00')
    ])
  })

UTC μ‹œκ°„λŒ€μ—μ„œ μ‹€ν–‰ν•  λ•Œλ§Œ μ„±κ³΅ν•©λ‹ˆλ‹€ ( "env": { "TZ": "UTC" } in launch.json ). λ‹€λ₯Έ μ‹œκ°„λŒ€μ—μ„œλŠ” ν…ŒμŠ€νŠΈκ°€ μ‹€νŒ¨ν•©λ‹ˆλ‹€.
@davidgoli κ°€ μ˜λ„ν•œ 것이며 여기에 λ­”κ°€ λΉ μ‘ŒμŠ΅λ‹ˆκΉŒ? κ·Έλ ‡λ‹€λ©΄ tzid λ§€κ°œλ³€μˆ˜λ₯Ό μ˜¬λ°”λ₯΄κ²Œ μ‚¬μš©ν•˜λŠ” 방법은 λ¬΄μ—‡μž…λ‹ˆκΉŒ? rrule μ§€μ •λœ μ‹œκ°„λŒ€μ—μ„œ μ‹€ν–‰λ˜λ„λ‘ μΆ”κ°€ν•œ 것 κ°™μŠ΅λ‹ˆλ‹€.

λ™μΌν•œ λ¬Έμ œκ°€ μžˆμ§€λ§Œ rrule.all()이 μžˆμŠ΅λ‹ˆλ‹€. UTCλŠ” μž‘λ™ν•˜μ§€λ§Œ λ‹€λ₯Έ μ‹œκ°„λŒ€λŠ” μ˜€ν”„μ…‹μ„ μ μš©ν•˜μ§€ μ•Šμ•„μ•Ό ν•  λ•Œ λ‹€μ‹œ μ μš©ν•©λ‹ˆλ‹€.

rrule-tz.js의 1849ν–‰κ³Ό 관련이 μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

var rezonedDate = rezoneIfNeeded(res, options);

rezoneIfNeeded λŠ” 이름과 달리 검사λ₯Ό μˆ˜ν–‰ν•˜μ§€ μ•ŠμœΌλ©° UTCκ°€ μ•„λ‹Œ ν•œ 항상 μ˜μ—­μ„ μž¬μ‘°μ •ν•©λ‹ˆλ‹€.

function rezoneIfNeeded(date, options) { return new datewithzone_DateWithZone(date, options.tzid).rezonedDate(); }

이미 μ˜¬λ°”λ₯΄κ²Œ κ΅¬μ—­ν™”λ˜μ–΄ μžˆλŠ”λ°λ„ λ‚ μ§œ ꡬ역을 λ³€κ²½ν•˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.

rezonedDate() λ₯Ό λ‹¨μˆœνžˆ this.date λ₯Ό λ°˜ν™˜ν•˜λ„λ‘ λ³€κ²½ν•˜λ©΄ λ¬Έμ œκ°€ ν•΄κ²°λ˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. λ‚΄κ°€ λ‹€λ₯Έ κ³³μ—μ„œ 무언가λ₯Ό κΉ¨λœ¨λ Έλ‹€κ³  μ™„μ „νžˆ ν™•μ‹ ν•  μˆ˜λŠ” μ—†μ§€λ§Œ, 얼핏 λ³΄κΈ°μ—λŠ” 이 변경이 이루어지면 λ‹€λ₯Έ λͺ¨λ“  것이 잘 μž‘λ™ν•˜λŠ” κ²ƒμ²˜λŸΌ λ³΄μž…λ‹ˆλ‹€.

rrule-tz.js의 1849ν–‰κ³Ό 관련이 μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

var rezonedDate = rezoneIfNeeded(res, options);

rezoneIfNeeded λŠ” 이름과 달리 검사λ₯Ό μˆ˜ν–‰ν•˜μ§€ μ•ŠμœΌλ©° UTCκ°€ μ•„λ‹Œ ν•œ 항상 μ˜μ—­μ„ μž¬μ‘°μ •ν•©λ‹ˆλ‹€.

function rezoneIfNeeded(date, options) { return new datewithzone_DateWithZone(date, options.tzid).rezonedDate(); }

이미 μ˜¬λ°”λ₯΄κ²Œ κ΅¬μ—­ν™”λ˜μ–΄ μžˆλŠ”λ°λ„ λ‚ μ§œ ꡬ역을 λ³€κ²½ν•˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.

이것은 μ •ν™•ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. rezonedDate λ©”μ„œλ“œλŠ” tzid κ°€ μ„€μ •λ˜μ–΄ μžˆλŠ”μ§€ ν™•μΈν•˜μ—¬ μ˜μ—­ μ˜€ν”„μ…‹μ„ μ μš©ν• μ§€ μ—¬λΆ€λ₯Ό κ²°μ •ν•©λ‹ˆλ‹€.

@agordeev 이 문제λ₯Ό μ‘°μ‚¬ν•˜κ² μŠ΅λ‹ˆλ‹€. @hlee5zebra 의 λ‹¨μˆœνžˆ μ‹œκ°„λŒ€ 지원을 μ œκ±°ν•˜λŠ” "μˆ˜μ •"은 ν•„μš”ν•˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. 두 경우 λͺ¨λ‘ tzid λ§€κ°œλ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠμœΌλ©΄ μ˜ˆμƒν•œ κ²°κ³Όλ₯Ό μ–»μŠ΅λ‹ˆκΉŒ?

κ·ΈλŸΌμ—λ„ λΆˆκ΅¬ν•˜κ³  RRuleκ³Ό RRuleSet λ™μž‘ κ°„μ˜ λΆˆμΌμΉ˜λŠ” 저와 관련이 있으며 더 μžμ„Ένžˆ μ‚΄νŽ΄λ΄μ•Ό ν•  버그일 수 μžˆμŠ΅λ‹ˆλ‹€. ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ κ°μ‚¬ν•©λ‹ˆλ‹€!

λ‚΄ 문제둜 이어진 λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€. λ‚΄ μ„œλ²„ μ½”λ“œκ°€ DTSTART κ°’ μ‹œκ°„μ„ μ˜¬λ°”λ₯΄κ²Œ μ²˜λ¦¬ν•˜μ§€ μ•Šκ³  TZID둜 μ§€μ •λœ μ‹œκ°„λŒ€μ— ν˜„μ§€ν™”ν•΄μ•Ό ν•  λ•Œ UTC둜 μ „λ‹¬ν–ˆμŠ΅λ‹ˆλ‹€. μ•„λ§ˆλ„ @agordeev λ¬Έμ œμ— 도움이 될 κ²ƒμž…λ‹ˆλ‹€. μ €λ₯Ό μ˜¬λ°”λ₯Έ λ°©ν–₯으둜 μ•ˆλ‚΄ν•΄ μ£Όμ‹  @davidgoli μ—κ²Œ κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€.

μ½”λ“œλ² μ΄μŠ€μ—μ„œ 문제λ₯Ό λ°œκ²¬ν•œ 것 κ°™μŠ΅λ‹ˆλ‹€. toString() λ©”μ†Œλ“œ datewithzone.ts TZIDκ°€ κ³΅κΈ‰λ˜λŠ” 좜λ ₯ UTC μ‹œκ°„μ„, κ·Έ λŒ€μ‹ μ— 좜λ ₯ν•΄μ•Ό ꡭ뢀적 μ‹œκ°„ 것이닀.

@hlee5zebra READMEμ—μ„œ 이 ν…μŠ€νŠΈλ₯Ό 기둝해 λ‘μ‹­μ‹œμ˜€.

https://github.com/jakubroztocil/rrule#important -use-utc-dates

μ€‘μš”: UTC λ‚ μ§œ μ‚¬μš©

JavaScript의 λ‚ μ§œλŠ” κΉŒλ‹€λ‘­μŠ΅λ‹ˆλ‹€. RRule은 ν•„μš”ν•œ 제3자 쒅속성을 크게 μΆ”κ°€ν•˜μ§€ μ•Šκ³  κ°€λŠ₯ν•œ ν•œ λ§Žμ€ μœ μ—°μ„±μ„ μ§€μ›ν•˜λ €κ³  μ‹œλ„ν•˜μ§€λ§Œ μ΄λŠ” μš°λ¦¬μ—κ²Œ λͺ‡ 가지 νŠΉλ³„ν•œ κ·œμΉ™λ„ μžˆμŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€.

기본적으둜 RRule은 "뢀동" μ‹œκ°„ λ˜λŠ” UTC μ‹œκ°„λŒ€λ₯Ό λ‹€λ£Ήλ‹ˆλ‹€. νŠΉμ • μ‹œκ°„λŒ€μ˜ κ²°κ³Όλ₯Ό μ›ν•˜λŠ” 경우 RRule은 μ‹œκ°„λŒ€ 지원도 μ œκ³΅ν•©λ‹ˆλ‹€. μ–΄λŠ μͺ½μ΄λ“ , JavaScript의 λ‚΄μž₯ "μ‹œκ°„λŒ€" μ˜€ν”„μ…‹μ€ λ°©ν•΄κ°€ λ˜λŠ” κ²½ν–₯이 μžˆμœΌλ―€λ‘œ 이 λΌμ΄λΈŒλŸ¬λ¦¬λŠ” λ‹¨μˆœνžˆ 그것을 μ „ν˜€ μ‚¬μš©ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λͺ¨λ“  μ‹œκ°„μ€ JavaScript에 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” κ²ƒμ²˜λŸΌ μ˜€ν”„μ…‹μ΄ 0인 μƒνƒœλ‘œ λ°˜ν™˜λ©λ‹ˆλ‹€.

결둠은 λ°˜ν™˜λœ "UTC" λ‚ μ§œλŠ” 항상 ν˜„μ§€ μ‹œκ°„λŒ€μ˜ λ‚ μ§œλ‘œ ν•΄μ„λœλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. μ΄λŠ” μ˜€ν”„μ…‹μ΄ 적용된 "μ˜¬λ°”λ₯Έ" ν˜„μ§€ μ‹œκ°„μ„ μ–»κΈ° μœ„ν•΄ μΆ”κ°€ λ³€ν™˜μ„ μˆ˜ν–‰ν•΄μ•Ό 함을 μ˜λ―Έν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ΄λŸ¬ν•œ 이유둜 UTC둜 νƒ€μž„μŠ€νƒ¬ν”„λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. μƒˆλ‘œμš΄ λ‚ μ§œ(Date.UTC(...)). λ°˜ν™˜λœ λ‚ μ§œλŠ” λ§ˆμ°¬κ°€μ§€λ‘œ UTC둜 ν‘œμ‹œλ©λ‹ˆλ‹€(항상 μ‹œκ°„λŒ€ μ˜€ν”„μ…‹μ΄ μžˆλŠ” λ‚ μ§œλ₯Ό λ°˜ν™˜ν•˜λŠ” Chrome μ œμ™Έ).

μΆ”κ°€ 주름은 λŒ€λΆ€λΆ„μ˜ JS κ΅¬ν˜„μ— μžˆμŠ΅λ‹ˆλ‹€. UTC μ˜€ν”„μ…‹ _λ˜λŠ”_ 둜컬 μ˜€ν”„μ…‹μ„ μ–»μ§€λ§Œ λ‘˜ 사이λ₯Ό μ „ν™˜ν•  μˆ˜λŠ” μ—†μŠ΅λ‹ˆλ‹€. 이 λ˜ν•œ κ΅¬ν˜„μ— 따라 λ‹€λ¦…λ‹ˆλ‹€. λ”°λΌμ„œ "UTC λ‚ μ§œ"κ°€ λ°˜ν™˜λ˜μ–΄ 일뢀 μœ„μΉ˜μ—μ„œλŠ” μ˜€ν”„μ…‹μ΄ ν¬ν•¨λœ toString() κ°€ 제곡되고 λ‹€λ₯Έ μœ„μΉ˜μ—μ„œλŠ” ν¬ν•¨λ˜μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄ Chromeμ—μ„œ:

> new Date(Date.UTC(2016, 10, 5))
Fri Nov 04 2016 17:00:00 GMT-0700 (Pacific Daylight Time)

ν•˜μ§€λ§Œ λ…Έλ“œμ—μ„œ:

> new Date(Date.UTC(2016, 10, 5))
2016-11-05T00:00:00.000Z

이것이 μ΅œμƒμ˜ κ²°κ³Όλ₯Ό μœ„ν•΄ toString() 값을 λ¬΄μ‹œν•˜κ³  toISOString() 및 getUTCHours() (etc) λ©”μ„œλ“œλ§Œ μ‚¬μš©ν•˜λŠ” μ΄μœ μž…λ‹ˆλ‹€.

λͺ¨λ“  λ‚ μ§œμ— λŒ€ν•΄ UTC λ°©λ²•λ§Œ μ‚¬μš©ν•˜κ³  ν˜„μ§€ μ‹œκ°„μœΌλ‘œ "해석"ν•˜λŠ” 이 μ ‘κ·Ό 방식을 μ‚¬μš©ν•˜λ©΄ rrule의 μ‹œκ°„λŒ€λ₯Ό κ³ λ €ν•  ν•„μš” 없이 rrule이 λ°˜ν™˜ν•œ λ‚ μ§œ 및 μ‹œκ°„μ— κ· μΌν•˜κ²Œ μ•‘μ„ΈμŠ€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ’‹μ•„, λ‚˜λŠ” 이 문제λ₯Ό μž¬ν˜„ν•  수 μžˆλ„λ‘ ν•˜κΈ° μœ„ν•΄ rrule.all() λ₯Ό μ•½κ°„ μˆ˜μ •ν•΄ μ™”μœΌλ©° λ‹€μŒμ€ 이 문제λ₯Ό μ•ˆμ •μ μœΌλ‘œ μž¬ν˜„ν•˜κΈ° μœ„ν•΄ 찾은 κ²ƒμž…λ‹ˆλ‹€.

  1. 'America/Adak', 'America/Chicago'(λ‚΄ ν˜„μ§€ μ‹œκ°„), 'America/New_York' 및 'UTC'의 각 μ‹œκ°„λŒ€ λ‚΄μ—μ„œ DTSTARTλ₯Ό μžμ •μœΌλ‘œ μ„€μ •ν•˜λ €κ³  μ‹œλ„ν–ˆμœΌλ©° κ²°κ³Ό rrule.toString() κ°€ μ •ν™•ν•˜κ²Œ μΈμ‡„λ©λ‹ˆλ‹€:
>> rRule.toString()
"DTSTART;TZID=America/Adak:20190718T000000
RRULE:FREQ=DAILY"

>> rRule.toString()
"DTSTART;TZID=America/Chicago:20190718T000000
RRULE:FREQ=DAILY"

>> rRule.toString()
"DTSTART;TZID=America/New_York:20190718T000000
RRULE:FREQ=DAILY"

>> rRule.toString()
"DTSTART:20190718T000000Z
RRULE:FREQ=DAILY"

건넀진 iterator ν•¨μˆ˜λ₯Ό κ±·λŠ” λ™μ•ˆ rrule.all() , 상기 제 νŒŒλΌλ―Έν„°μ˜ 첫번째 μΈμŠ€ν„΄μŠ€ date ν„΄ 아웃 될 각 κ²½μš°λ§ˆλ‹€ μ‹œκ°„λŒ€ λ‹€μŒ Date 톡해 인쇄 .toISOString() :

아메리카/μ•„λ‹₯:
"2019-07-18T04:00:00.000Z"

λ―Έκ΅­/μ‹œμΉ΄κ³ :
"2019-07-18T00:00:00.000Z"

λ―Έκ΅­/λ‰΄μš•:
"2019-07-17T23:00:00.000Z"

UTC:
"2019-07-18T00:00:00.000Z"

μ‹œκ°„λŒ€κ°€ UTC둜 μ„€μ •λ˜μ§€ μ•Šμ€ 경우(예: America/Adak, America/New_York) ν˜„μ§€ μ‹œκ°„κ³Ό μ„ νƒν•œ μ‹œκ°„λŒ€ μ‚¬μ΄μ˜ μ˜€ν”„μ…‹μ„ DTSTART λ‚ μ§œμ—μ„œ λΉΌλŠ” κ²ƒμ²˜λŸΌ λ³΄μž…λ‹ˆλ‹€. λ”°λΌμ„œ λ‚΄ ν˜„μ§€ μ‹œκ°„κ³Ό λ‰΄μš• κ°„μ˜ μ˜€ν”„μ…‹μ΄ +1μ΄λ―€λ‘œ New York ISO λ¬Έμžμ—΄μ€ 23:00을 ν‘œμ‹œν•©λ‹ˆλ‹€. 이 μ˜€ν”„μ…‹μ„ 2019λ…„ 7μ›” 18일 μžμ •μ—μ„œ λΉΌλ©΄ κ²°κ³ΌλŠ” 07/17일 μ˜€ν›„ 11μ‹œκ°€ λ©λ‹ˆλ‹€. /2019.

ν•˜μ§€λ§Œ UTCμ—μ„œλŠ” 이런 일이 λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” 점에 μœ μ˜ν•˜μ‹­μ‹œμ˜€.

이것이 문제일 수 μžˆλ‹€κ³  μƒκ°ν•©λ‹ˆκΉŒ, μ•„λ‹ˆλ©΄ λ‚΄κ°€ 놓쳀을 수 μžˆλŠ” μˆ˜ν–‰ν•΄μ•Ό ν•˜λŠ” 일뢀 ꡬ성이 μžˆμŠ΅λ‹ˆκΉŒ?

λ‚΄κ°€ λ³Έ 것에 λŒ€ν•œ ν•΄κ²° λ°©λ²•μœΌλ‘œ λ‹€μŒμ„ μˆ˜ν–‰ν–ˆμœΌλ©° JavaScript의 Date 의 μ •ν™•ν•œ μΈμŠ€ν„΄μŠ€λ₯Ό μ•ˆμ •μ μœΌλ‘œ 얻을 수 μžˆλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.

rRule.all(function (date, i) {
    if (this.getSelectedTzid() !== 'UTC') {
        date = moment.tz({
            year: date.getUTCFullYear(),
            month: date.getUTCMonth(),
            date: date.getUTCDate(),
            hours: date.getUTCHours(),
            minutes: date.getUTCMinutes()
        }, this.getLocalTzid()).toDate();
    }

    ...
}.bind(this));

@hlee5zebra 예, getUTCxxx 방법을 μ‚¬μš©ν•˜λŠ” μ ‘κ·Ό 방식은 readmeμ—μ„œ ꢌμž₯ν•˜λŠ” μ˜¬λ°”λ₯Έ μ ‘κ·Ό λ°©μ‹μž…λ‹ˆλ‹€.

μœ μ‚¬ UTC λ‚ μ§œλŠ” UTC μ‹œκ°„μœΌλ‘œ 거의 _μ‹€μ œλ‘œ_ λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. UTCλŠ” "쀑립" μ‹œκ°„λŒ€κ°€ λ˜λ„λ‘ μ˜€λ²„λ‘œλ“œλ˜λ―€λ‘œ getUTCxxx λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μ›λž˜ μ‹œκ°„λŒ€μ— 관계없이 _local_ μ‹œκ°„μ„ 검색할 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ 이유둜 tzid λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³ λ„ ν˜„μ§€ ν‘œμ€€ μ‹œκ°„λŒ€μ—μ„œ ν˜„μ§€ ν‘œμ€€ μ‹œκ°„λŒ€λ₯Ό μ‚¬μš©ν•˜λŠ” 것과 λ™μΌν•œ λ™μž‘μ„ μ˜ˆμƒν•΄μ•Ό ν•©λ‹ˆλ‹€. tzid λŠ” _λ‹€λ₯Έ μ‹œκ°„λŒ€μ—μ„œ_ λ˜ν’€μ΄λ˜λŠ” ν˜„μž¬ ν˜„μ§€ μ‹œκ°„μ„ κ°€μ Έμ˜€λŠ” 데만 μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€. 항상 μ‚¬μš©μžμ˜ ν˜„μ§€ μ‹œκ°„λŒ€λ‘œ λ˜ν’€μ΄ν•˜λ €λ©΄ tzid λ©λ‹ˆλ‹€.

이것이 이 라이브러리λ₯Ό λ‹€μ‹œ μž‘μ„±ν•  λ•Œ λ‚΄μž₯ JS Date 객체λ₯Ό μ „ν˜€ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” μ΄μœ μž…λ‹ˆλ‹€. λ„ˆλ¬΄ ν˜Όλž€μŠ€λŸ½κΈ°λ§Œ ν•©λ‹ˆλ‹€.

@agordeev 이 문제λ₯Ό μ‘°μ‚¬ν•˜κ² μŠ΅λ‹ˆλ‹€. @hlee5zebra 의 λ‹¨μˆœνžˆ μ‹œκ°„λŒ€ 지원을 μ œκ±°ν•˜λŠ” "μˆ˜μ •"은 ν•„μš”ν•˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. 두 경우 λͺ¨λ‘ tzid λ§€κ°œλ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠμœΌλ©΄ μ˜ˆμƒν•œ κ²°κ³Όλ₯Ό μ–»μŠ΅λ‹ˆκΉŒ?

λ‹΅λ³€ κ°μ‚¬ν•©λ‹ˆλ‹€.

    const rrule = new RRule({
      freq: RRule.WEEKLY,
      dtstart: new Date(Date.UTC(2019, 6, 17, 18, 0, 0)),
      // tzid: 'America/Los_Angeles',
      count: 10,
      interval: 1,
      wkst: RRule.SU,
      byweekday: [RRule.MO, RRule.TU, RRule.WE, RRule.FR, RRule.SA]
    })

생산:

  -  [Date: 2019-07-17T18:00:00.000Z]
  -  [Date: 2019-07-19T18:00:00.000Z]
  -  [Date: 2019-07-20T18:00:00.000Z]
  -  [Date: 2019-07-22T18:00:00.000Z]
  etc..

λ”°λΌμ„œ λ‚ μ§œ/μ‹œκ°„μ€ μ •ν™•ν•˜μ§€λ§Œ μ‹œκ°„λŒ€λŠ” UTCμž…λ‹ˆλ‹€. rrule은 tzid λ§€κ°œλ³€μˆ˜λ₯Ό μƒλž΅ν•  λ•Œ UTC의 DTSTARTλ₯Ό κ³ λ €ν•©λ‹ˆλ‹€.

항상 μ‚¬μš©μžμ˜ ν˜„μ§€ μ‹œκ°„λŒ€λ‘œ λ˜ν’€μ΄ν•˜λ €λ©΄ tzidλ₯Ό μ‚¬μš©ν•˜λ©΄ μ•ˆ λ©λ‹ˆλ‹€.

μ‚¬μš©μžμ˜ μ‹œκ°„λŒ€μ—μ„œ λ˜ν’€μ΄ν•˜λŠ” μœ μΌν•œ μ˜΅μ…˜μ€ ν•΄λ‹Ή μ‹œκ°„λŒ€λ₯Ό tzid λ§€κ°œλ³€μˆ˜λ‘œ μ „λ‹¬ν•˜λŠ” 것뿐이라고 μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€. λΌμ΄λΈŒλŸ¬λ¦¬λŠ” μ„œλ²„μ—μ„œ node.js와 ν•¨κ»˜ μ‚¬μš©λœλ‹€λŠ” 점을 염두에 λ‘μ‹­μ‹œμ˜€.

_μ‹œκ°„λŒ€μ— 관계없이_ μ‚¬μš©μžμ˜ ν˜„μ§€ μ‹œκ°„μœΌλ‘œ 반볡이 1800에 μžˆμ„ 경우 tzid λ₯Ό μ‚¬μš©ν•  ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€. README: https://github.com/jakubroztocil/rrule#important -use-utc-dates에 μ„€λͺ…λœ "뢀동" μ‹œκ°„μ— λŒ€ν•΄ μ½μ—ˆλŠ”μ§€ ν™•μΈν•˜μ‹­μ‹œμ˜€.

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰