How to produce recurrence rschedule durations with timeshifts
Asked Answered
L

1

2

I am using rSchedule to produce working hour intervals.But timezone is ignored. How can I achieve it?

The input is working hour intervals in a day, with timezone as below.

const input = {
  workingHours:[{start:9, end:12}, {start:13, end:18}], 
  timeZone:'Europe/Berlin'
};

With the below code, I am expecting to produce intervals with respect to day light shiftings in a year. However, the produced output ignores the timeZone I provided.

import { Schedule } from "@rschedule/core/generators";
import '@rschedule/moment-tz-date-adapter/setup';
import moment from 'moment-timezone';

const schedule = new Schedule({
      rrules: [
        {
          frequency: "MONTHLY",//frequency: "WEEKLY",
          //byDayOfWeek: ["MO", 'TU', 'WE', 'TH', 'FR'],
          duration:1000 * 60 * 60 * 3,//input.workingHours[0].end-input.workingHours[0].start,
          byHourOfDay:[12],//input.workingHours[0].end
          timezone:'Europe/Berlin',//input.timeZone,

          start: moment(Date.UTC(2019, 0, 1)),
          end: moment(Date.UTC(2020, 0, 0))
        }
      ]
    });

    schedule.occurrences().toArray().forEach(adapter => {
      console.log(
          {
            start: adapter.date.toISOString(),
            end: adapter.end.toISOString(),
          }
        )
    })

Output ignoring timezone:

 { start: '2019-01-01T09:00:00.000Z', end: '2019-01-01T12:00:00.000Z' }
 { start: '2019-02-01T09:00:00.000Z', end: '2019-02-01T12:00:00.000Z' }
 { start: '2019-03-01T09:00:00.000Z', end: '2019-03-01T12:00:00.000Z' }
 { start: '2019-04-01T09:00:00.000Z', end: '2019-04-01T12:00:00.000Z' }
 { start: '2019-05-01T09:00:00.000Z', end: '2019-05-01T12:00:00.000Z' }
 { start: '2019-06-01T09:00:00.000Z', end: '2019-06-01T12:00:00.000Z' }
 { start: '2019-07-01T09:00:00.000Z', end: '2019-07-01T12:00:00.000Z' }
 { start: '2019-08-01T09:00:00.000Z', end: '2019-08-01T12:00:00.000Z' }
 { start: '2019-09-01T09:00:00.000Z', end: '2019-09-01T12:00:00.000Z' }
 { start: '2019-10-01T09:00:00.000Z', end: '2019-10-01T12:00:00.000Z' }
 { start: '2019-11-01T09:00:00.000Z', end: '2019-11-01T12:00:00.000Z' }
 { start: '2019-12-01T09:00:00.000Z', end: '2019-12-01T12:00:00.000Z' }

Expected output:

{ start: '2019-01-01T11:00:00.000Z', end: '2019-01-01T14:00:00.000Z' },
{ start: '2019-02-01T11:00:00.000Z', end: '2019-02-01T14:00:00.000Z' },
{ start: '2019-03-01T11:00:00.000Z', end: '2019-03-01T14:00:00.000Z' },
{ start: '2019-04-01T10:00:00.000Z', end: '2019-04-01T13:00:00.000Z' },
{ start: '2019-05-01T10:00:00.000Z', end: '2019-05-01T13:00:00.000Z' },
{ start: '2019-06-01T10:00:00.000Z', end: '2019-06-01T13:00:00.000Z' },
{ start: '2019-07-01T10:00:00.000Z', end: '2019-07-01T13:00:00.000Z' },
{ start: '2019-08-01T10:00:00.000Z', end: '2019-08-01T13:00:00.000Z' },
{ start: '2019-09-01T10:00:00.000Z', end: '2019-09-01T13:00:00.000Z' },
{ start: '2019-10-01T10:00:00.000Z', end: '2019-10-01T13:00:00.000Z' },
{ start: '2019-11-01T11:00:00.000Z', end: '2019-11-01T14:00:00.000Z' },
{ start: '2019-12-01T11:00:00.000Z', end: '2019-12-01T14:00:00.000Z' }
Largish answered 8/11, 2019 at 20:36 Comment(1)
Because in moment you've not set the timezone. You are calling moment wuthout any tz set to it.Studio
E
1

Because I'm not familiar with these timezone's (and don't know what timezone the "expected output" is suppose to be in), it's a little unclear what you expect to happen. But as @JorgeFuentesGonzález pointed out in a comment, an issue is probably that you aren't providing the start datetime in the proper timezone.

As pointed out in the rSchedule source code (which should conveniently show up as a tooltip in editors like VSCode--edit I've gone ahead and clarified this in the rSchedule docs as well), the timezone config option for Rule objects does not change the timezone the rule is in, it changes the timezone the rule is displayed in. This distinction is important for the internal functioning of rSchedule, but I can see in this case it is unclear.

So your rule is generating occurrences in your local timezone (because start: moment(Date.UTC(2019, 0, 1)) generates a local moment), and then those occurrences are being transformed into the 'Europe/Berlin' timezone before being output. Except wait! That's not what's happening. This Rule is part of a Schedule, so it's the schedule's timezone which determines the output timezone of occurrences. The schedule appears to have no timezone (so it is in the local timezone). So I think the rule is in the local timezone, and the output dates are in the local timezone.

  • Note: console logging using toISOString() may be obfuscating the fact that your output dates are in your local timezone, rather than whatever timezone you expect.

Depending on what you are trying to accomplish, I'd suggest something like the following:

import { Schedule } from "@rschedule/core/generators";
import '@rschedule/moment-tz-date-adapter/setup';
import moment from 'moment-timezone';

const schedule = new Schedule({
  rrules: [
    {
      frequency: "MONTHLY",//frequency: "WEEKLY",
      duration:1000 * 60 * 60 * 3,//input.workingHours[0].end-input.workingHours[0].start,
      byHourOfDay:[12],//input.workingHours[0].end
      start: moment.tz(Date.UTC(2019, 0, 1), 'Europe/Berlin'),
      end: moment.tz(Date.UTC(2020, 0, 0), 'Europe/Berlin')
    }
  ],
  timezone:'Europe/Berlin'
});

Codesandbox demo here.

Let me know if you're still not seeing what you expect.

Euthenics answered 8/11, 2019 at 22:15 Comment(2)
Your suggestion worked, thanks @john. The output date is in UTC, since I used date.toISOString(). Just as a comment as an early user of the rschedule library, I saw an rschedule rule as an interface/contract to create recurrence dates(milliseconds since epoch) regardless of the output timezone. Because it is straightforward to change the output format and timezone with other libraries. So, I expected start and end to be again milliseconds since epoch and the timezone field to handle the time shifts while generating recurrences.Anatase
Milliseconds since epoch is the UTC timezone. If rSchedule only processed dates in UTC, it would ignore DST shifts.Euthenics

© 2022 - 2024 — McMap. All rights reserved.