Rrule: рдпреВрдЯреАрд╕реА-рд▓реЗрдХрд┐рди-рдирд╣реАрдВ-рдпреВрдЯреАрд╕реА рднреНрд░рдо

рдХреЛ рдирд┐рд░реНрдорд┐рдд 5 рдЕрдкреНрд░реИрд▓ 2019  ┬╖  18рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: jakubroztocil/rrule

рдореБрдЭреЗ рд╕рдВрджреЗрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдирд┐рдпрдо рдХреЗ рд╕рд╛рде рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореЗрд░реА рд╕рдордЭ рдФрд░/рдпрд╛ рдЗрд╕рдХреЗ рдЯрд╛рдЗрдордЬрд╝реЛрди рд╕рдорд░реНрдерди рдХреЗ рд╕рд╛рде рд╣реИред рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╣реА rrule рдФрд░ luxon рдХреЗ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдореЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рдЕрдиреБрднрд╛рдЧ рдкрдврд╝ рд▓рд┐рдП рд╣реИрдВред

рдХреЛрдб рдирдореВрдирд╛

const { RRule, RRuleSet } = require(`rrule`);

const dtstart = new Date();
console.log(`dtstart`, dtstart);

const firstHour = dtstart.getHours();
const secondHour = (firstHour + 2) % 24;

const getRRule = options => new RRule(Object.assign({}, options, {
    freq: RRule.DAILY,
    count: 1,
    dtstart,
    byminute: 0,
    bysecond: 0
}));

const showNextInstance = tzid => {
    const ruleSet = new RRuleSet();
    ruleSet.rrule(getRRule({ tzid, byhour: firstHour }));
    ruleSet.rrule(getRRule({ tzid, byhour: secondHour }));
    console.log(tzid, ruleSet.after(dtstart));
};

showNextInstance(undefined);
showNextInstance(`UTC`);
showNextInstance(`local`);
showNextInstance(`America/Chicago`);

рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЖрдЙрдЯрдкреБрдЯ

dtstart 2019-04-05T11:51:23.744Z
undefined 2019-04-06T06:00:00.744Z
UTC 2019-04-06T06:00:00.744Z
local 2019-04-06T06:00:00.744Z
America/Chicago 2019-04-06T06:00:00.744Z

рдЕрдкреЗрдХреНрд╖рд┐рдд рдЙрддреНрдкрд╛рджрди

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ tzid рдХреЗ рд╡рд┐рдирд┐рд░реНрджреЗрд╢рди рдХрд╛ рдЖрдЙрдЯрдкреБрдЯ рдкрд░ рдХреБрдЫ рдкреНрд░рднрд╛рд╡ рдкрдбрд╝реЗрдЧрд╛, рд▓реЗрдХрд┐рди рдкреНрд░рддреНрдпреЗрдХ рдЯрд╛рдЗрдордЬрд╝реЛрди рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рдЖрдЙрдЯрдкреБрдЯ рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИред

рдореИрдВ рдпрд╣ рднреА рдирд╣реАрдВ рджреЗрдЦ рд╕рдХрддрд╛ рдХрд┐ рдирд┐рдпрдореЛрдВ рдореЗрдВ рджрд┐рдП рдЧрдП рд╕рдордп рдФрд░ рдЕрдЧрд▓реЗ рдИрд╡реЗрдВрдЯ рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдХреЗ рдЖрдЙрдЯрдкреБрдЯ рдХреЗ рдмреАрдЪ рдХреНрдпрд╛ рд╕рдВрдмрдВрдз рд╣реИред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдЕрдЧрд▓рд╛ рдЙрджрд╛рд╣рд░рдг рдореЛрдЯреЗ рддреМрд░ рдкрд░ рдЖрдкреВрд░реНрддрд┐ рдХрд┐рдП рдЧрдП рдирд┐рдпрдореЛрдВ рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдП рдЧрдП рджреЛ рдШрдВрдЯреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реЛрдЧрд╛, рдЬреЛ рдЗрд╕ рдмрд╛рдд рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдирд┐рд░реНрджрд┐рд╖реНрдЯ dtstart рдФрд░ tzid рдорд╛рдиреЛрдВ рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдпрд╛ рд▓рд╛рдЧреВ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдирд┐рдпрдо рд╕рдВрд╕реНрдХрд░рдг

2.6.0

рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо

рдУрдПрд╕ рдПрдХреНрд╕ 10.14.2, рдиреЛрдб 8.11.4

рд╕реНрдерд╛рдиреАрдп рд╕рдордпрдХреНрд╖реЗрддреНрд░

$ date
Fri Apr  5 06:32:33 CDT 2019

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ Date рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд╕рд╛рде рдореБрджреНрджреЛрдВ рдХреЛ рд╕реБрд▓рдЭрд╛рдирд╛ рдЖрд╕рд╛рди рд╣реИ рдФрд░ RRULE рд▓рд┐рдП рдШрдЯрдирд╛рдУрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдПрдВ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рджреЛрдиреЛрдВ рдХреЗ рд╕рдВрдпреЛрдЬрди рд╕реЗ рдкрд╣рд▓реЗ рдЙрдирдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрд▓рдЧ рд╕реЗ рдмрд╛рдд рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВред рдореБрдЭреЗ рдЗрд╕реЗ рдЬреНрдпрд╛рджрд╛рддрд░ рд▓рд┐рдЦрдирд╛ рдкрдбрд╝рд╛ рддрд╛рдХрд┐ рдореИрдВ рд╕рдорд╕реНрдпрд╛ рдХреА рдЕрдкрдиреА рд╕рдордЭ рдХреЛ рд╕реБрд▓рдЭрд╛ рд╕рдХреВрдВ рдФрд░ рдореБрдЭреЗ рд▓рдЧрд╛ рдХрд┐ рдЕрдЧрд░ рдпрд╣ рджреВрд╕рд░реЛрдВ рдХреА рдорджрдж рдХрд░рддрд╛ рд╣реИ рддреЛ рдореИрдВ рдпрд╣рд╛рдВ рдкреЛрд╕реНрдЯ рдХрд░реВрдВрдЧрд╛ред

рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рджрд┐рдирд╛рдВрдХ рд╡рд╕реНрддреБ

рдореИрдВ рдЗрд╕ рдмрд╛рдд рд╕реЗ рд╕рд╣рдордд рдирд╣реАрдВ рд╣реВрдВ рдХрд┐ JS Date рд╡рд╕реНрддреБ рдЕрдирд┐рдпрдорд┐рдд рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд╕реНрддреБ рдХреЗ рд╕рд╛рде рд╕рд╛рдорд╛рдиреНрдп рдЧрд▓рддрдлрд╣рдорд┐рдпрд╛рдВ рд╣реИрдВ рдЬреЛ рдРрд╕рд╛ рдкреНрд░рддреАрдд рдХрд░рддреА рд╣реИрдВред рдпрд╣ рдХрдо рд╕реЗ рдХрдо рдХрд╣рдиреЗ рдореЗрдВ рднреНрд░рдорд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рд╣реИред

рдЬреИрд╕рд╛ рдХрд┐ @ hlee5zebra рдиреЗ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рд╣реИ, Date рдХрдиреНрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЗ рд╕рд╛рде рдмрдирд╛рдИ рдЧрдИ рддрд┐рдерд┐рдпрд╛рдВ рд╣рдореЗрд╢рд╛ рдпреВрдЯреАрд╕реА рдореЗрдВ рджрд░реНрд╢рд╛рдпреА рдЬрд╛рддреА рд╣реИрдВред рдЙрдиреНрд╣реЗрдВ рд╕реНрдерд╛рдиреАрдп рд╕рдордп рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкрд░реНрджреЗ рдХреЗ рдкреАрдЫреЗ рд╡реЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпреВрдирд┐рдХреНрд╕ рдпреБрдЧ рдореЗрдВ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреЗ рд╣реИрдВред рд╣рдо рддрддреНрдХрд╛рд▓ Date рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ .getTime() рдпрд╛ .toISOString() рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рд╣рдо рдЦреБрдж рдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛ рд╕рдХреЗрдВ рдХрд┐ рд╣рдо рдпреВрдЯреАрд╕реА рдореЗрдВ рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВред

рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рднреА рдпреВрдЯреАрд╕реА рдореЗрдВ рд╕рднреА рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХрд░рдиреЗ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдкреНрд░рджрд░реНрд╢рди рдкрд░ рдХреЗрд╡рд▓ рд╕реНрдерд╛рдиреАрдп рд╕рдордп рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рд╕рдореНрдореЗрд▓рди рдХрд╛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкрд╛рд▓рди рдХрд░рддрд╛ рд╣реИред рдРрд╕рд╛ рд╣реА рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рд╣рдо, рдбреЗрд╡рд▓рдкрд░, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╣реИрдВ; рд▓реЗрдХрд┐рди рдлрд┐рд░ рд╣рдорд╛рд░реЗ рдорди рдореЗрдВ рд╣рдорд╛рд░рд╛ рдЕрдкрдирд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рдкрд╛рдиреА рдХреЛ рдЧрдВрджрд╛ рдХрд░ рджреЗрддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдРрдкреНрд╕ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рддреЗ рд╕рдордп, рд╣рдореЗрдВ рд╕рдореНрдореЗрд▓рди рдХрд╛ рдкрд╛рд▓рди рдХрд░рдирд╛ рдФрд░ рд╣рдорд╛рд░реЗ рдмреИрдХрдПрдВрдб рдореЗрдВ рдпреВрдЯреАрд╕реА рдХреЗ рд░реВрдк рдореЗрдВ рддрд┐рдерд┐рдпреЛрдВ рдХреЛ рд╕рд╣реЗрдЬрдирд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП (рдЬреЗрдПрд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдпреВрдЯреАрд╕реА рдореЗрдВ рддрд╛рд░реАрдЦреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИ рдЗрд╕рд▓рд┐рдП рд╣рдо рд╡рд╣рд╛рдВ рдЕрдЪреНрдЫреЗ рд╣реИрдВ)ред рдпрджрд┐ рдЖрдк рдЕрдкрдиреЗ рдбреЗрдЯрд╛ рд╕реНрдЯреЛрд░ рдореЗрдВ рддрд╛рд░реАрдЦреЛрдВ рдХреЛ рдпреВрдЯреАрд╕реА рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЙрдиреНрд╣реЗрдВ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рдкрд╛рд╕ рдЖрдИрдПрд╕рдУ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╣реБрдВрдЪрдирд╛ рдЪрд╛рд╣рд┐рдП, Date рдСрдмреНрдЬреЗрдХреНрдЯ рджреНрд╡рд╛рд░рд╛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкрд╛рд░реНрд╕ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд╕реНрдерд╛рдиреАрдп рд╕рдордп рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдмрд┐рдирд╛ рдХреЛрдИ рднрд╛рд░реА рднрд╛рд░ рдЙрдард╛рдПред

рдЗрд╕ рд▓реЗрдЦрди рдиреЗ рдореБрдЭреЗ Date рд╡рд╕реНрддреБ рдХреЛ рд╕рдордЭрдиреЗ рдФрд░ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдореЗрдВ рдорджрдж рдХреА рд╣реИ рдХрд┐ рдореИрдВ рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд┐рддрдирд╛ рдХреБрдЫ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ: https://www.toptal.com/software/definitive-guide-to-datetime-manipulation

рд░реВрд▓

RRULE рд▓рд┐рдП рдШрдЯрдирд╛рдУрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпреВрдЯреАрд╕реА рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдкреЗрдХреНрд╖рд╛ рдФрд░ рддрд┐рдерд┐рдпреЛрдВ рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдореВрд▓рднреВрдд рдЕрдВрддрд░ рд╣реЛрддрд╛ рд╣реИ, рдЬрдм рдпреЗ рджреЛ рдмрд╛рд░ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдПрдХ рджрд┐рди рдХреА рдмрд╛рдзрд╛ рдХреЛ рдкрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рд╣рдорд╛рд░рд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рддреНрдпреЗрдХ рдордВрдЧрд▓рд╡рд╛рд░ рдХреЛ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдЪрд╛рд╣рддрд╛ рд╣реИ, рддреЛ рд╡реЗ рдЙрдореНрдореАрдж рдХрд░реЗрдВрдЧреЗ рдХрд┐ рд╕рднреА рдШрдЯрдирд╛рдПрдВ рдЙрдирдХреЗ рд╕реНрдерд╛рдиреАрдп рд╕рдордп рдореЗрдВ рдордВрдЧрд▓рд╡рд╛рд░ рдХреЛ рд╣реЛрдВрдЧреАред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╕рднреА рдЧрдгрдирд╛ рдпреВрдЯреАрд╕реА рдореЗрдВ рдХреА рдЬрд╛рддреА рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП RRULE рдЬреИрд╕реЗ:

DTSTART:2019-10-29T00:02:26Z
RRULE:FREQ=WEEKLY;BYWEEKDAY=TU

рдпреВрдЯреАрд╕реА рдореЗрдВ рдордВрдЧрд▓рд╡рд╛рд░ рдХреЛ рдШрдЯрдирд╛рдПрдБ рд▓реМрдЯрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдкреНрд░рд╛рдЗрдо рдореЗрд░рд┐рдбрд┐рдпрди рдХреЗ рдХрд╛рдлреА рдкрд╢реНрдЪрд┐рдо рдореЗрдВ рд╕реНрдерд┐рдд рдХрд┐рд╕реА рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП, рд╕реНрдерд╛рдиреАрдп рд╕рдордп рдореЗрдВ рд╕реЛрдорд╡рд╛рд░ рдХреЛ рдШрдЯрдирд╛рдПрдБ рджрд┐рдЦрд╛рдИ рджреЗрдВрдЧреА, рдЬреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡рд╣ рдкрд░рд┐рдгрд╛рдо рдирд╣реАрдВ рд╣реИ рдЬрд┐рд╕рдХреА рдХрд┐рд╕реА рдХреЛ рдЙрдореНрдореАрдж рд╣реИред

рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рд╕рдордЭрдирд╛

рдЬреЛ рдХреБрдЫ рднреА рдХрд╣рд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рдХреЗ рд▓рд┐рдП рдбреЗрд╡рд▓рдкрд░ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдпрд╣ рд╕реЛрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░рдирд╛ рд╣реИ рдХрд┐ рд╕реНрдерд╛рдиреАрдп рддрд┐рдерд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдпреВрдЯреАрд╕реА рддрд┐рдерд┐ рд╣реИ, рдЙрд╕ "рдирдХрд▓реА" рддрд┐рдерд┐ рдХреЛ rrule.js , рдФрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рдЗрд╕рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ рдпрд╣ рд╕реНрдерд╛рдиреАрдп рдпреВрдЯреАрд╕реА рд╕рдордпред рдЬрдм рдЖрдк .all() рд╡рд┐рдзрд┐ рд╕реЗ рдШрдЯрдирд╛рдПрдБ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЙрди рддрд┐рдерд┐рдпреЛрдВ рдХреЗ "UTC" рднрд╛рдЧреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдирдИ Date рд╡рд╕реНрддреБрдУрдВ рдХреЛ рддреБрд░рдВрдд рдЪрд╛рд▓реВ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдкреНрд░рднрд╛рд╡реА рд░реВрдк рд╕реЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рдЕрдкреЗрдХреНрд╖рд╛ рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИред

import { RRule } from 'rrule'

const dtstart = new Date('2019-10-29T00:02:26Z') // same as: `new Date(Date.UTC(2019, 9, 29, 0, 2, 26))`
console.log(dtstart.toISOString()) // 2019-10-29T00:02:26.000Z
console.log(dtstart) // Mon Oct 28 2019 17:02:26 GMT-0700 (Pacific Daylight Time)

const fakeDateStart = setPartsToUTCDate(dtstart)
console.log(fakeDateStart.toISOString()) // 2019-10-28T17:02:26.000Z
console.log(fakeDateStart) // Mon Oct 28 2019 10:02:26 GMT-0700 (Pacific Daylight Time)

const rule = new RRule({
  freq: RRule.WEEKLY,
  byweekday: [RRule.TU],
  count: 2,
  dtstart: fakeDateStart
})

const localUTCOccurrences = rule.all()
console.log(localUTCOccurrences.map(toISOString)) // ["2019-10-29T17:02:26.000Z", "2019-11-05T17:02:26.000Z"]
console.log(localUTCOccurrences) // [Tue Oct 29 2019 10:02:26 GMT-0700 (Pacific Daylight Time), Tue Nov 05 2019 09:02:26 GMT-0800 (Pacific Standard Time)]

const occurrences = localUTCOccurrences.map(setUTCPartsToDate)
console.log(occurrences.map(toISOString)) // ["2019-10-30T00:02:26.000Z", "2019-11-06T01:02:26.000Z"]
console.log(occurrences) // [Tue Oct 29 2019 17:02:26 GMT-0700 (Pacific Daylight Time), Tue Nov 05 2019 17:02:26 GMT-0800 (Pacific Standard Time)]

function setPartsToUTCDate(d) {
  return new Date(
    Date.UTC(
      d.getFullYear(),
      d.getMonth(),
      d.getDate(),
      d.getHours(),
      d.getMinutes(),
      d.getSeconds()
    )
  )
}

function setUTCPartsToDate(d) {
  return new Date(
    d.getUTCFullYear(),
    d.getUTCMonth(),
    d.getUTCDate(),
    d.getUTCHours(),
    d.getUTCMinutes(),
    d.getUTCSeconds()
  )
}

function toISOString(d) {
  return d.toISOString()
}

https://codesandbox.io/s/rrule-localutc-conversion-zxlki

рдпрд╛ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ:

import { RRule } from 'rrule'

const date = new Date('2019-10-29T00:02:26Z')

const rule = new RRule({
  freq: RRule.WEEKLY,
  byweekday: [RRule.TU],
  count: 2,
  dtstart: setPartsToUTCDate(date)
})

const occurrences = rule.all().map(setUTCPartsToDate)

https://codesandbox.io/s/rrule-localutc-conversion-in-short-ez7g0

рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдореИрдВ рджреЗрдЦ рд╕рдХрддрд╛ рд╣реВрдВ, рдХреНрд░реЛрдо, рдлрд╝рд╛рдпрд░рдлрд╝реЙрдХреНрд╕ рдФрд░ рд╕рдлрд╛рд░реА рд╕рднреА рддрд╛рд░реАрдЦреЛрдВ рдХреЛ рд╕реНрдерд╛рдиреАрдп рд╕рдордп рдореЗрдВ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬрдм рдХрдВрд╕реЛрд▓ рдкрд░ рд▓реЙрдЧ рдЗрди рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ Node.js UTC рдореЗрдВ ISO рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЗ рд░реВрдк рдореЗрдВред

рд╕рднреА 18 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдореИрдВ рднреА рдмрд╣реБрдд рднреНрд░рдорд┐рдд рд╣реВрдБред

рдареАрдХ рд╣реИ, рдореБрдЭреЗ рдорд┐рд▓ рдЧрдпрд╛, рд░реАрдбрдореА рдореЗрдВ рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдкреИрд░рд╛рдЧреНрд░рд╛рдл рдерд╛:

image

рдЖрдкрдХреЛ рд╕реНрдерд╛рдиреАрдп рд╕рдордп рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдЗрди рджреЛ рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдпрджрд┐ рдЖрдк tzid рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ X рдЯрд╛рдЗрдордЬрд╝реЛрди рдХреЗ рд▓рд┐рдП рдСрдлрд╝рд╕реЗрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдСрдлрд╝рд╕реЗрдЯ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

/**
 * Mutates date. Add timezone to the date.
 *
 * <strong i="9">@param</strong> {Date} [date]
 */
export function localizeDate(date = new Date()) {
  const offset = new Date().getTimezoneOffset() * 60 * 1000; // get offset for local timezone (can modify here to support tzid)
  date.setTime(date.getTime() - offset);
  return date;
}

/**
 * Mutates a date. De-timezones a date.
 *
 * <strong i="10">@param</strong> {Date} [date]
 */
export function utcifyDate(date = new Date()) {
  const offset = new Date().getTimezoneOffset() * 60 * 1000; // get offset for local timezone (can modify here to support tzid)
  date.setTime(date.getTime() + offset);
  return date;
}

рддрдм рдЖрдкрдХрд╛ рдХреЛрдб рдмрджрд▓ рдЬрд╛рдПрдЧрд╛:

const { RRule, RRuleSet } = require(`rrule`);

const dtstart = localizeDate(new Date());
console.log(`dtstart`, utcifyDate(new Date(dtstart))); // even though it is utc string, this is the local time

const firstHour = dtstart.getUTCHours();
const secondHour = (firstHour + 2) % 24;

const getRRule = options => new RRule(Object.assign({}, options, {
    freq: RRule.DAILY,
    count: 1,
    dtstart,
    byminute: 0,
    bysecond: 0
}));

const showNextInstance = tzid => {
    const ruleSet = new RRuleSet();
    ruleSet.rrule(getRRule({ byhour: firstHour })); // remove tzid as i dont support this
    ruleSet.rrule(getRRule({ byhour: secondHour })); // removed tzid as i dont support this
    console.log('local:', utcifyDate(ruleSet.after(dtstart));
};

showNextInstance(undefined);
showNextInstance(`UTC`);
showNextInstance(`local`);
showNextInstance(`America/Chicago`);

рдореБрдЭреЗ рд╕рдВрджреЗрд╣ рд╣реИ рдХрд┐ рдЗрд╕ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рдЗрд╕рдХреЗ рдЖрд╕рдкрд╛рд╕ рдПрдХ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЬреЗрдПрд╕ рдХреЗ рднреНрд░рдорд┐рдд рдФрд░ рдЕрдирд┐рдпрдорд┐рдд Date рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдореИрдВ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдПрдХ рдкреВрд░реНрдг рдкреБрдирд░реНрд▓реЗрдЦрди рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рдареАрдХ рдХрд░рдиреЗ рдореЗрдВ рдХреБрдЫ рд╕рдордп рд▓рдЧреЗрдЧрд╛ред

рдзрдиреНрдпрд╡рд╛рдж @davidgoli рдЖрдкрдХрд╛ рдХрд╛рдо рдмрд╣реБрдд рд╣реА рд╕рд░рд╛рд╣рдиреАрдп рд╣реИ !!!

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдореЗрдВ рдХрд┐рд╕реА рдРрд╕реЗ рд╡реНрдпрдХреНрддрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдЕрдирд┐рдпрдорд┐рдд рддрд┐рдерд┐ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рд╕рдордЭрдиреЗ рдореЗрдВ рджреВрд╕рд░реЛрдВ рдХреА рдорджрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓реЗрдЦ рд▓рд┐рдЦрдирд╛ рд╕рдордЭрддрд╛ рд╣реЛред рдореИрдВ рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ рдЕрднреА рднреА рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реВрдВ, рдореИрдВрдиреЗ рдЪреАрдЬреЛрдВ рдХреЛ рддрдм рддрдХ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрдм рддрдХ рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ред

рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реЛрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рд▓реМрдЯрд╛рдИ рдЧрдИ рддрд╛рд░реАрдЦ рдЬрд┐рд╕реЗ рдЖрдк рдХрдВрд╕реЛрд▓ рдкрд░ рдкреНрд░рд┐рдВрдЯ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рд╡рд╣ рдПрдХ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рддрд┐рдерд┐ рд╣реИ рдЬрд┐рд╕реЗ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ, рдФрд░ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдпреВрдЯреАрд╕реА рдореЗрдВ рдХрдВрд╕реЛрд▓ рдХреЗ рд▓рд┐рдП рддрд┐рдерд┐рдпреЛрдВ рдХреЛ рдкреНрд░рд┐рдВрдЯ рдХрд░рддрд╛ рд╣реИ (рдЕрдкрдиреЗ рдЯрд╛рдЗрдорд╕реНрдЯреИрдореНрдк рдХреЗ рдЕрдВрдд рдореЗрдВ 'рдЬреЗрдб' рджреЗрдЦреЗрдВ рдЬреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рд╢реВрдиреНрдп рдСрдлрд╕реЗрдЯ)ред рдЪреВрдВрдХрд┐ рдЖрдкрдХреЗ рдЪрд╛рд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдореЗрдВ рдЕрдЧрд▓реА рдШрдЯрдирд╛рдПрдВ рдПрдХ рд╣реА рд╕рдордп рдкрд░ рд╣реЛ рд░рд╣реА рд╣реИрдВ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕рдордп рдХреНрд╖реЗрддреНрд░реЛрдВ рдореЗрдВ), рдпрд╣ рдареАрдХ рдЙрд╕реА рдЯрд╛рдЗрдорд╕реНрдЯреИрдореНрдк рдХреЛ рдЪрд╛рд░ рдмрд╛рд░ рдкреНрд░рд┐рдВрдЯ рдХрд░ рд░рд╣рд╛ рд╣реИред

рдпрд╣ рднреА рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ Date рдСрдмреНрдЬреЗрдХреНрдЯ 00:00:00 UTC, рдЧреБрд░реБрд╡рд╛рд░, 1 рдЬрдирд╡рд░реА 1970 (рд╡рд╣рд╛рдВ "UTC" рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ!), рдорд┐рд▓реАрд╕реЗрдХрдВрдб рдХреА рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдордп рдХрд╛ рдЯреНрд░реИрдХ рд░рдЦрддрд╛ рд╣реИ, рдХреБрдЫ рджреНрд╡рд╛рд░рд╛ рдирд╣реАрдВ "12:34:56 рдЕрдкрд░рд╛рд╣реНрди" рдпрд╛ рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреА рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреА рддрд░рд╣ред

@davidgoli

рдореИрдВ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдПрдХ рдкреВрд░реНрдг рдкреБрдирд░реНрд▓реЗрдЦрди рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рдареАрдХ рдХрд░рдиреЗ рдореЗрдВ рдХреБрдЫ рд╕рдордп рд▓рдЧреЗрдЧрд╛ред

рдЖрдк rSchedule рдХреЗ рд╕реНрд░реЛрдд рдХреЛ рджреЗрдЦрдирд╛ DateTime рдСрдмреНрдЬреЗрдХреНрдЯ (рд▓рдХреНрд╕рди рд╕реЗ рдирд╣реАрдВ) рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдЗрдирдкреБрдЯ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдПрдХ рдлреНрд▓реЛрдЯрд┐рдВрдЧ рдпреВрдЯреАрд╕реА рддрд┐рдерд┐ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЗрдирдкреБрдЯ рдХреЗ рдмрд░рд╛рдмрд░ рджрд┐рдЦрддрд╛ рд╣реИ ред рдЗрд╕ рдпреВрдЯреАрд╕реА рдбреЗрдЯрд╛рдЯрд╛рдЗрдо рдХреЗ рд╕рд╛рде рдЗрдЯрд░реЗрд╢рди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЗрд╕рд▓рд┐рдП рдбреАрдПрд╕рдЯреА рдХреЛрдИ рдореБрджреНрджрд╛ рдирд╣реАрдВ рд╣реИред рдПрдХ рдШрдЯрдирд╛ рдорд┐рд▓рдиреЗ рдХреЗ рдмрд╛рдж, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдЗрд╕реЗ рджреЗрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЗрд╕реЗ рдЙрдЪрд┐рдд рд╕рдордп рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдп рддрд┐рдерд┐ рдореЗрдВ рд╡рд╛рдкрд╕ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП: рдпрд╣ рддрд┐рдерд┐

import { DateTime as LuxonDateTime } from 'luxon';

const date = LuxonDateTime.fromObject({
  year: 2019,
  month: 1,
  day: 1,
  zone: 'America/Los_Angeles'
})

рдЗрд╕ рдпреВрдЯреАрд╕реА рддрд┐рдерд┐ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рд╕рдордп рдХреНрд╖реЗрддреНрд░ рд╕рд╣реЗрдЬрд╛ рдЬрд╛рдПрдЧрд╛

const fakeDate = Date.UTC(2019, 0, 1)
const fakeDateZone = 'America/Los_Angeles'

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрд╣ рдпреВрдЯреАрд╕реА рддрд┐рдерд┐ рд▓рдХреНрд╕рди рддрд┐рдерд┐ рдХреЗ рд╕рдорд╛рди рджрд┐рдЦрддреА рд╣реИ (рд╡реЗ рджреЛрдиреЛрдВ 2019/1/1 рддрд░рд╣ рджрд┐рдЦрддреА рд╣реИрдВ) рд▓реЗрдХрд┐рди, рдЪреВрдВрдХрд┐ рд╡реЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕рдордп рдХреНрд╖реЗрддреНрд░реЛрдВ рдореЗрдВ рд╣реИрдВ, рд╡реЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рд╣реА рд╕рдордп рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред

рдпрд╣ рдХрд╣рд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ, рдЗрд╕ рд╡рд┐рд╢реЗрд╖ "рдпреВрдЯреАрд╕реА" рддрд┐рдерд┐ рдХреЗ рд╕рд╛рде рдкреБрдирд░рд╛рд╡реГрддрд┐ рдХрд░рдиреЗ рд╕реЗ рд╣рдо рджрд┐рди рдХреЗ рдЙрдЬрд╛рд▓реЗ рдХреА рдмрдЪрдд рдХреЗ рд╕рдордп рдХреА рдЪрд┐рдВрддрд╛ рдХрд┐рдП рдмрд┐рдирд╛ рдкреБрдирд░рд╛рд╡реГрддрд┐ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╕рд╣реА рддрд┐рдерд┐ рдорд┐рд▓рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рд╡рд╛рдкрд╕ рд▓рдХреНрд╕рди рддрд┐рдерд┐ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

LuxonDateTime.fromObject({
  year: fakeDate.year,
  month: fakeDate.month,
  day: fakeDate.day,
  zone: fakeDateZone,
})

рдпрд╣ рдпреВрдЯреАрд╕реА рдХреЗ рдЕрдиреБрдХреВрд▓ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рддрд░реНрдХ рдХреЛ рдЕрдЪреНрдЫрд╛ рд░рдЦрддрд╛ рд╣реИ рдЬрдмрдХрд┐ рдЕрднреА рднреА рдордирдорд╛рдирд╛ рд╕рдордпрдХреНрд╖реЗрддреНрд░ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред

@thefliik рдореБрдЭреЗ рдЖрджрд┐рдо рдиреАрдЪреЗ рдорд┐рд▓ рдЧрдП; рдпрд╣ рдРрд╕реЗ рд╕рдкреНрддрд╛рд╣ рд╣реИрдВ рдЬреЛ рдпрд╣рд╛рдБ рдЕрд╕рд▓реА рд╕рд┐рд░рджрд░реНрдж рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐ рдореИрдВ рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдБ рдХрд┐ rschedule рдиреЗ рднреА (рдЕрдм рддрдХ) byweekno рдФрд░ bysetpos рд╕рдорд░реНрдерди рдкрд░ рдкрдВрдЯ рдХрд┐рдпрд╛ рд╣реИ ...

рдЕрд░реЗ рд╣рд╛рдВред byweekno рдмрд╣реБрдд рдХрд╖реНрдЯрдкреНрд░рдж рд╣реИред

рдХреЛрдИ рдЦрдмрд░?

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ Date рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд╕рд╛рде рдореБрджреНрджреЛрдВ рдХреЛ рд╕реБрд▓рдЭрд╛рдирд╛ рдЖрд╕рд╛рди рд╣реИ рдФрд░ RRULE рд▓рд┐рдП рдШрдЯрдирд╛рдУрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдПрдВ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рджреЛрдиреЛрдВ рдХреЗ рд╕рдВрдпреЛрдЬрди рд╕реЗ рдкрд╣рд▓реЗ рдЙрдирдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрд▓рдЧ рд╕реЗ рдмрд╛рдд рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВред рдореБрдЭреЗ рдЗрд╕реЗ рдЬреНрдпрд╛рджрд╛рддрд░ рд▓рд┐рдЦрдирд╛ рдкрдбрд╝рд╛ рддрд╛рдХрд┐ рдореИрдВ рд╕рдорд╕реНрдпрд╛ рдХреА рдЕрдкрдиреА рд╕рдордЭ рдХреЛ рд╕реБрд▓рдЭрд╛ рд╕рдХреВрдВ рдФрд░ рдореБрдЭреЗ рд▓рдЧрд╛ рдХрд┐ рдЕрдЧрд░ рдпрд╣ рджреВрд╕рд░реЛрдВ рдХреА рдорджрдж рдХрд░рддрд╛ рд╣реИ рддреЛ рдореИрдВ рдпрд╣рд╛рдВ рдкреЛрд╕реНрдЯ рдХрд░реВрдВрдЧрд╛ред

рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рджрд┐рдирд╛рдВрдХ рд╡рд╕реНрддреБ

рдореИрдВ рдЗрд╕ рдмрд╛рдд рд╕реЗ рд╕рд╣рдордд рдирд╣реАрдВ рд╣реВрдВ рдХрд┐ JS Date рд╡рд╕реНрддреБ рдЕрдирд┐рдпрдорд┐рдд рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд╕реНрддреБ рдХреЗ рд╕рд╛рде рд╕рд╛рдорд╛рдиреНрдп рдЧрд▓рддрдлрд╣рдорд┐рдпрд╛рдВ рд╣реИрдВ рдЬреЛ рдРрд╕рд╛ рдкреНрд░рддреАрдд рдХрд░рддреА рд╣реИрдВред рдпрд╣ рдХрдо рд╕реЗ рдХрдо рдХрд╣рдиреЗ рдореЗрдВ рднреНрд░рдорд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рд╣реИред

рдЬреИрд╕рд╛ рдХрд┐ @ hlee5zebra рдиреЗ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рд╣реИ, Date рдХрдиреНрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЗ рд╕рд╛рде рдмрдирд╛рдИ рдЧрдИ рддрд┐рдерд┐рдпрд╛рдВ рд╣рдореЗрд╢рд╛ рдпреВрдЯреАрд╕реА рдореЗрдВ рджрд░реНрд╢рд╛рдпреА рдЬрд╛рддреА рд╣реИрдВред рдЙрдиреНрд╣реЗрдВ рд╕реНрдерд╛рдиреАрдп рд╕рдордп рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкрд░реНрджреЗ рдХреЗ рдкреАрдЫреЗ рд╡реЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпреВрдирд┐рдХреНрд╕ рдпреБрдЧ рдореЗрдВ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреЗ рд╣реИрдВред рд╣рдо рддрддреНрдХрд╛рд▓ Date рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ .getTime() рдпрд╛ .toISOString() рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рд╣рдо рдЦреБрдж рдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛ рд╕рдХреЗрдВ рдХрд┐ рд╣рдо рдпреВрдЯреАрд╕реА рдореЗрдВ рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВред

рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рднреА рдпреВрдЯреАрд╕реА рдореЗрдВ рд╕рднреА рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХрд░рдиреЗ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдкреНрд░рджрд░реНрд╢рди рдкрд░ рдХреЗрд╡рд▓ рд╕реНрдерд╛рдиреАрдп рд╕рдордп рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рд╕рдореНрдореЗрд▓рди рдХрд╛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкрд╛рд▓рди рдХрд░рддрд╛ рд╣реИред рдРрд╕рд╛ рд╣реА рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рд╣рдо, рдбреЗрд╡рд▓рдкрд░, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╣реИрдВ; рд▓реЗрдХрд┐рди рдлрд┐рд░ рд╣рдорд╛рд░реЗ рдорди рдореЗрдВ рд╣рдорд╛рд░рд╛ рдЕрдкрдирд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рдкрд╛рдиреА рдХреЛ рдЧрдВрджрд╛ рдХрд░ рджреЗрддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдРрдкреНрд╕ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рддреЗ рд╕рдордп, рд╣рдореЗрдВ рд╕рдореНрдореЗрд▓рди рдХрд╛ рдкрд╛рд▓рди рдХрд░рдирд╛ рдФрд░ рд╣рдорд╛рд░реЗ рдмреИрдХрдПрдВрдб рдореЗрдВ рдпреВрдЯреАрд╕реА рдХреЗ рд░реВрдк рдореЗрдВ рддрд┐рдерд┐рдпреЛрдВ рдХреЛ рд╕рд╣реЗрдЬрдирд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП (рдЬреЗрдПрд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдпреВрдЯреАрд╕реА рдореЗрдВ рддрд╛рд░реАрдЦреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИ рдЗрд╕рд▓рд┐рдП рд╣рдо рд╡рд╣рд╛рдВ рдЕрдЪреНрдЫреЗ рд╣реИрдВ)ред рдпрджрд┐ рдЖрдк рдЕрдкрдиреЗ рдбреЗрдЯрд╛ рд╕реНрдЯреЛрд░ рдореЗрдВ рддрд╛рд░реАрдЦреЛрдВ рдХреЛ рдпреВрдЯреАрд╕реА рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЙрдиреНрд╣реЗрдВ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рдкрд╛рд╕ рдЖрдИрдПрд╕рдУ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╣реБрдВрдЪрдирд╛ рдЪрд╛рд╣рд┐рдП, Date рдСрдмреНрдЬреЗрдХреНрдЯ рджреНрд╡рд╛рд░рд╛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкрд╛рд░реНрд╕ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд╕реНрдерд╛рдиреАрдп рд╕рдордп рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдмрд┐рдирд╛ рдХреЛрдИ рднрд╛рд░реА рднрд╛рд░ рдЙрдард╛рдПред

рдЗрд╕ рд▓реЗрдЦрди рдиреЗ рдореБрдЭреЗ Date рд╡рд╕реНрддреБ рдХреЛ рд╕рдордЭрдиреЗ рдФрд░ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдореЗрдВ рдорджрдж рдХреА рд╣реИ рдХрд┐ рдореИрдВ рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд┐рддрдирд╛ рдХреБрдЫ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ: https://www.toptal.com/software/definitive-guide-to-datetime-manipulation

рд░реВрд▓

RRULE рд▓рд┐рдП рдШрдЯрдирд╛рдУрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпреВрдЯреАрд╕реА рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдкреЗрдХреНрд╖рд╛ рдФрд░ рддрд┐рдерд┐рдпреЛрдВ рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдореВрд▓рднреВрдд рдЕрдВрддрд░ рд╣реЛрддрд╛ рд╣реИ, рдЬрдм рдпреЗ рджреЛ рдмрд╛рд░ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдПрдХ рджрд┐рди рдХреА рдмрд╛рдзрд╛ рдХреЛ рдкрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рд╣рдорд╛рд░рд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рддреНрдпреЗрдХ рдордВрдЧрд▓рд╡рд╛рд░ рдХреЛ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдЪрд╛рд╣рддрд╛ рд╣реИ, рддреЛ рд╡реЗ рдЙрдореНрдореАрдж рдХрд░реЗрдВрдЧреЗ рдХрд┐ рд╕рднреА рдШрдЯрдирд╛рдПрдВ рдЙрдирдХреЗ рд╕реНрдерд╛рдиреАрдп рд╕рдордп рдореЗрдВ рдордВрдЧрд▓рд╡рд╛рд░ рдХреЛ рд╣реЛрдВрдЧреАред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╕рднреА рдЧрдгрдирд╛ рдпреВрдЯреАрд╕реА рдореЗрдВ рдХреА рдЬрд╛рддреА рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП RRULE рдЬреИрд╕реЗ:

DTSTART:2019-10-29T00:02:26Z
RRULE:FREQ=WEEKLY;BYWEEKDAY=TU

рдпреВрдЯреАрд╕реА рдореЗрдВ рдордВрдЧрд▓рд╡рд╛рд░ рдХреЛ рдШрдЯрдирд╛рдПрдБ рд▓реМрдЯрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдкреНрд░рд╛рдЗрдо рдореЗрд░рд┐рдбрд┐рдпрди рдХреЗ рдХрд╛рдлреА рдкрд╢реНрдЪрд┐рдо рдореЗрдВ рд╕реНрдерд┐рдд рдХрд┐рд╕реА рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП, рд╕реНрдерд╛рдиреАрдп рд╕рдордп рдореЗрдВ рд╕реЛрдорд╡рд╛рд░ рдХреЛ рдШрдЯрдирд╛рдПрдБ рджрд┐рдЦрд╛рдИ рджреЗрдВрдЧреА, рдЬреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡рд╣ рдкрд░рд┐рдгрд╛рдо рдирд╣реАрдВ рд╣реИ рдЬрд┐рд╕рдХреА рдХрд┐рд╕реА рдХреЛ рдЙрдореНрдореАрдж рд╣реИред

рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рд╕рдордЭрдирд╛

рдЬреЛ рдХреБрдЫ рднреА рдХрд╣рд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рдХреЗ рд▓рд┐рдП рдбреЗрд╡рд▓рдкрд░ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдпрд╣ рд╕реЛрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░рдирд╛ рд╣реИ рдХрд┐ рд╕реНрдерд╛рдиреАрдп рддрд┐рдерд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдпреВрдЯреАрд╕реА рддрд┐рдерд┐ рд╣реИ, рдЙрд╕ "рдирдХрд▓реА" рддрд┐рдерд┐ рдХреЛ rrule.js , рдФрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рдЗрд╕рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ рдпрд╣ рд╕реНрдерд╛рдиреАрдп рдпреВрдЯреАрд╕реА рд╕рдордпред рдЬрдм рдЖрдк .all() рд╡рд┐рдзрд┐ рд╕реЗ рдШрдЯрдирд╛рдПрдБ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЙрди рддрд┐рдерд┐рдпреЛрдВ рдХреЗ "UTC" рднрд╛рдЧреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдирдИ Date рд╡рд╕реНрддреБрдУрдВ рдХреЛ рддреБрд░рдВрдд рдЪрд╛рд▓реВ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдкреНрд░рднрд╛рд╡реА рд░реВрдк рд╕реЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рдЕрдкреЗрдХреНрд╖рд╛ рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИред

import { RRule } from 'rrule'

const dtstart = new Date('2019-10-29T00:02:26Z') // same as: `new Date(Date.UTC(2019, 9, 29, 0, 2, 26))`
console.log(dtstart.toISOString()) // 2019-10-29T00:02:26.000Z
console.log(dtstart) // Mon Oct 28 2019 17:02:26 GMT-0700 (Pacific Daylight Time)

const fakeDateStart = setPartsToUTCDate(dtstart)
console.log(fakeDateStart.toISOString()) // 2019-10-28T17:02:26.000Z
console.log(fakeDateStart) // Mon Oct 28 2019 10:02:26 GMT-0700 (Pacific Daylight Time)

const rule = new RRule({
  freq: RRule.WEEKLY,
  byweekday: [RRule.TU],
  count: 2,
  dtstart: fakeDateStart
})

const localUTCOccurrences = rule.all()
console.log(localUTCOccurrences.map(toISOString)) // ["2019-10-29T17:02:26.000Z", "2019-11-05T17:02:26.000Z"]
console.log(localUTCOccurrences) // [Tue Oct 29 2019 10:02:26 GMT-0700 (Pacific Daylight Time), Tue Nov 05 2019 09:02:26 GMT-0800 (Pacific Standard Time)]

const occurrences = localUTCOccurrences.map(setUTCPartsToDate)
console.log(occurrences.map(toISOString)) // ["2019-10-30T00:02:26.000Z", "2019-11-06T01:02:26.000Z"]
console.log(occurrences) // [Tue Oct 29 2019 17:02:26 GMT-0700 (Pacific Daylight Time), Tue Nov 05 2019 17:02:26 GMT-0800 (Pacific Standard Time)]

function setPartsToUTCDate(d) {
  return new Date(
    Date.UTC(
      d.getFullYear(),
      d.getMonth(),
      d.getDate(),
      d.getHours(),
      d.getMinutes(),
      d.getSeconds()
    )
  )
}

function setUTCPartsToDate(d) {
  return new Date(
    d.getUTCFullYear(),
    d.getUTCMonth(),
    d.getUTCDate(),
    d.getUTCHours(),
    d.getUTCMinutes(),
    d.getUTCSeconds()
  )
}

function toISOString(d) {
  return d.toISOString()
}

https://codesandbox.io/s/rrule-localutc-conversion-zxlki

рдпрд╛ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ:

import { RRule } from 'rrule'

const date = new Date('2019-10-29T00:02:26Z')

const rule = new RRule({
  freq: RRule.WEEKLY,
  byweekday: [RRule.TU],
  count: 2,
  dtstart: setPartsToUTCDate(date)
})

const occurrences = rule.all().map(setUTCPartsToDate)

https://codesandbox.io/s/rrule-localutc-conversion-in-short-ez7g0

рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдореИрдВ рджреЗрдЦ рд╕рдХрддрд╛ рд╣реВрдВ, рдХреНрд░реЛрдо, рдлрд╝рд╛рдпрд░рдлрд╝реЙрдХреНрд╕ рдФрд░ рд╕рдлрд╛рд░реА рд╕рднреА рддрд╛рд░реАрдЦреЛрдВ рдХреЛ рд╕реНрдерд╛рдиреАрдп рд╕рдордп рдореЗрдВ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬрдм рдХрдВрд╕реЛрд▓ рдкрд░ рд▓реЙрдЧ рдЗрди рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ Node.js UTC рдореЗрдВ ISO рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЗ рд░реВрдк рдореЗрдВред

@ рдЯрд┐рдо-рдлрд┐рд▓рд┐рдкреНрд╕ рдореИрдВ рднреА рдЕрднреА рдЗрд╕рдХреЗ рд▓рд┐рдП рдкреАрдбрд╝рд┐рдд рд╣реВрдВ рдФрд░ рдЗрд╕рдХреЗ рдЖрд╕рдкрд╛рд╕ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдмрдВрджрд░ рдкреИрдЪ рдвреВрдВрдв рд░рд╣рд╛ рд╣реВрдВред

рдореЗрд░реЗ рдкрд╛рд╕ 8 рдмрдЬреЗ рдИрдПрд╕рдЯреА рдкрд░ рдПрдХ рдкреБрдирд░рд╛рд╡рд░реНрддреА рдШрдЯрдирд╛ рд╣реИ рдЬреЛ рдареАрдХ рдХрд╛рдо рдХрд░рддреА рд╣реИ, рд▓реЗрдХрд┐рди 9 рдмрдЬреЗ рдИрдПрд╕рдЯреА рдЗрд╕реЗ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рджрд┐рди рдореЗрдВ рд╡рд╛рдкрд╕ рдзрдХреЗрд▓ рд░рд╣реА рд╣реИред

рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрддреНрд╕реБрдХ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдЖрдкрдХреЛ рдЗрд╕рдХрд╛ рдЙрддреНрддрд░ рдорд┐рд▓ рд╕рдХрддрд╛ рд╣реИред

@ рдЯрд┐рдо-рдлрд┐рд▓рд┐рдкреНрд╕ рдЬреЛ рдПрдХ рдЙрддреНрдХреГрд╖реНрдЯ рдмреНрд░реЗрдХрдбрд╛рдЙрди рд╣реИред рдореИрдВ рдЕрднреА рднреА рдЗрд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдореБрдЭреЗ рдЕрдВрдд рдореЗрдВ рд╕рдордЭрдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛, рдзрдиреНрдпрд╡рд╛рдж!

@ рдЯрд┐рдо-рдлрд┐рд▓рд┐рдкреНрд╕ рдЖрдкрдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдХреНрдпрд╛ рдЖрдк рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХрд╛ рд╕рдорд╛рдзрд╛рди рдЕрднреА рднреА рдЖрдкрдХреЗ рдХрдВрдкреНрдпреВрдЯрд░ рдХреЗ рд╕реНрдерд╛рдиреАрдп рд╕рдордп рдХреНрд╖реЗрддреНрд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдмреБрдзрд╡рд╛рд░ рдХреЛ рд╡рд╛рдкрд╕ рдЖ рд╕рдХрддрд╛ рд╣реИред

image

@tonylau рдЕрдкрдиреЗ рдХрдВрд╕реЛрд▓ рдореЗрдВ рдЯрд╛рдЗрдордЬрд╝реЛрди рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рдЖрдкрдХреЛ рджрд┐рдирд╛рдВрдХ рдХреЗ рдХреБрдЫ рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП getUTC*() рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреЛ рдЖрдкрдХреЗ рд╕реНрдерд╛рдиреАрдп рд╕рдордп рдХреНрд╖реЗрддреНрд░ рдХреА рдкрд░рд╡рд╛рд╣ рдХрд┐рдП рдмрд┐рдирд╛ рд╕рдорд╛рди рд╣реЛрдВрдЧреЗред

@davidgoli

рдореИрдВрдиреЗ рдЕрдкрдирд╛ рдЯрд╛рдЗрдордЬрд╝реЛрди рдпреВрдЯреАрд╕реА+14 (рдХрд┐рд░реАрдЯрд┐рдорд╛рдЯреА рдЖрдЗрд▓реИрдВрдб/рд▓рд╛рдЗрди рдЖрдЗрд▓реИрдВрдбреНрд╕ рдЯрд╛рдЗрдо) рдкрд░ рд╕реЗрдЯ рдХрд┐рдпрд╛ рд╣реИ рдФрд░ рдЬрдм рдореИрдВ getUTCDay() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рддрдм рднреА рдореБрдЭреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдорд┐рд▓рд╛ред рд╡рд╣ рджрд┐рди рдЕрднреА рднреА рдмреБрдзрд╡рд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реМрдЯрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рдЙрд╕реЗ рдордВрдЧрд▓рд╡рд╛рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП?

рд╕реИрдВрдбрдмреЙрдХреНрд╕: https://codesandbox.io/s/rrule-localutc-conversion-in-short-0uzt1

image

рдЗрд╕ рдЪрд░реНрдЪрд╛ рдХреЗ рд▓рд┐рдП рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ: https://github.com/tc39/proposal-temporal

@ рдЯрд┐рдо-рдлрд┐рд▓рд┐рдкреНрд╕ рдзрдиреНрдпрд╡рд╛рдж!!!!!!!!!! рд╡рд╣ рдмрд╣реБрдд рдорджрджрдЧрд╛рд░ рдерд╛!!!!!!! рдХреНрдпрд╛ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдирд┐рдпрдо рдХреЗ рд╕рд╛рде рдЖрдИрд╕реАрдПрд╕ рдХреИрд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ? рдЬрдм рдореИрдВ рдиреЛрдб рдореЗрдВ рдЖрдИрд╕реАрдПрд╕ рдкреИрдХреЗрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ рдФрд░ рдЬрдм рдореБрдЭреЗ рдХреИрд▓реЗрдВрдбрд░ рдЖрдордВрддреНрд░рдг рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ, рддреЛ рд╡реЗ рдПрдХ рджрд┐рди рдХреА рдЫреБрдЯреНрдЯреА рдкрд░ рд╣реЛрддреЗ рд╣реИрдВред (рд▓реЗрдХрд┐рди рдореИрдВ рдЖрдкрдХреЗ рдХреЛрдб рдХреЗ рдХрд╛рд░рдг рдЕрдкрдиреЗ рдбреАрдмреА рдореЗрдВ рд╕рдм рдХреБрдЫ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдбрд╛рд▓рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реВрдВ !! рдмрд╣реБрдд-рдмрд╣реБрдд рдзрдиреНрдпрд╡рд╛рджред)

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

zeluspudding picture zeluspudding  ┬╖  11рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

fatshotty picture fatshotty  ┬╖  5рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

spurreiter picture spurreiter  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

mapidemic picture mapidemic  ┬╖  7рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

berardo picture berardo  ┬╖  9рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ