Skip to content

Commit

Permalink
[RAM] Fix snooze scheduler timezone handling (elastic#157338)
Browse files Browse the repository at this point in the history
## Summary

Closes elastic#156535 

The Snooze Scheduler was failing to properly save and load snoozes if
the user selected a timezone other than the Kibana default. This is
because the datepicker only converts timestamp values between UTC and
the default Kibana timezone.

This PR fixes the issue by offsetting all dates that come in and out of
the scheduler UI relative to local time.

To test, create a snooze like this on `main` and make sure you select
timezone America/Los_Angeles. (If your local timezone is equivalent to
America/Los_Angeles, select a different timezone)

<img width="426" alt="Screenshot 2023-05-10 at 3 58 57 PM"
src="https://github.com/elastic/kibana/assets/1445834/ab95c47c-30a0-44d5-bd9d-45fdb929193d">

On `main`, editing the snooze will (erroneously) display the wrong
times:

<img width="423" alt="Screenshot 2023-05-10 at 4 03 24 PM"
src="https://github.com/elastic/kibana/assets/1445834/ff28ccdd-f491-43ce-87cd-d606c8d71c64">

Repeating this process on this PR's branch will save a snooze with the
correct `dtstart` and consequently load the correct snooze time.
  • Loading branch information
Zacqary authored May 17, 2023
1 parent 2e4858b commit 213a697
Showing 1 changed file with 29 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,21 @@ const RuleSnoozeSchedulerPanel: React.FunctionComponent<PanelOpts> = ({
...(initialSchedule.rRule.until ? { until: moment(initialSchedule.rRule.until) } : {}),
} as RecurrenceSchedule);

// Ensure intitial datetimes are displayed in the initial timezone
const startMoment = moment(initialSchedule.rRule.dtstart).tz(initialSchedule.rRule.tzid);
const dtstartOffsetToKibanaTz = moment()
.tz(defaultTz)
.year(startMoment.year())
.month(startMoment.month())
.date(startMoment.date())
.hour(startMoment.hour())
.minute(startMoment.minute())
.second(startMoment.second())
.millisecond(startMoment.millisecond())
.toISOString();
return {
startDT: moment(initialSchedule.rRule.dtstart),
endDT: moment(initialSchedule.rRule.dtstart).add(initialSchedule.duration, 'ms'),
startDT: moment(dtstartOffsetToKibanaTz),
endDT: moment(dtstartOffsetToKibanaTz).add(initialSchedule.duration, 'ms'),
isRecurring,
recurrenceSchedule,
selectedTimezone: [{ label: initialSchedule.rRule.tzid }],
Expand Down Expand Up @@ -218,6 +230,19 @@ const RuleSnoozeSchedulerPanel: React.FunctionComponent<PanelOpts> = ({

const onClickSaveSchedule = useCallback(() => {
if (!startDT || !endDT) return;

const tzid = selectedTimezone[0].label ?? defaultTz;
// Convert the dtstart from Kibana timezone to the selected timezone
const dtstart = moment()
.tz(tzid)
.year(startDT.year())
.month(startDT.month())
.date(startDT.date())
.hour(startDT.hour())
.minute(startDT.minute())
.second(startDT.second())
.toISOString();

const recurrence =
isRecurring && recurrenceSchedule
? recurrenceSchedule
Expand All @@ -227,8 +252,8 @@ const RuleSnoozeSchedulerPanel: React.FunctionComponent<PanelOpts> = ({
onSaveSchedule({
id: initialSchedule?.id ?? uuidv4(),
rRule: {
dtstart: startDT.toISOString(),
tzid: selectedTimezone[0].label ?? defaultTz,
dtstart,
tzid,
...recurrence,
},
duration: endDT.valueOf() - startDT.valueOf(),
Expand Down

0 comments on commit 213a697

Please sign in to comment.