fix: Ensure rendering as UTC to prevent browser tz from messing up times

## What does this PR do?

Fixes all date shifts that are due browser time, by ensuring everything is UTC so it's not transformed to different times.

The times weren't actually shifting, dates were, but after casting these to UTC properly the times were also shifting; so that was a bug after a bugfix, time wise it was only a problem to determine all day events (which didn't completely work)

### Yes, but how do I test this?

Before:
Create a all day date override in +05:30
Shift your local system time to -04:00
Note that the day is different

After - do the same:
The day is the same!

Fixes #8365
Fixes #6978
Fixes #6482
pull/10119/head
Alex van Andel 2023-07-13 02:32:11 +02:00 committed by GitHub
parent 9b37d65503
commit 605f7d35ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 12 additions and 10 deletions

View File

@ -3,11 +3,11 @@ import { useState } from "react";
import { Controller, useFieldArray, useForm } from "react-hook-form";
import { z } from "zod";
import dayjs from "@calcom/dayjs";
import { DateOverrideInputDialog, DateOverrideList } from "@calcom/features/schedules";
import Schedule from "@calcom/features/schedules/components/Schedule";
import Shell from "@calcom/features/shell/Shell";
import { availabilityAsString } from "@calcom/lib/availability";
import { yyyymmdd } from "@calcom/lib/date-fns";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { useTypedQuery } from "@calcom/lib/hooks/useTypedQuery";
import { HttpError } from "@calcom/lib/http-error";
@ -56,6 +56,7 @@ const DateOverride = ({ workingHours }: { workingHours: WorkingHours[] }) => {
const { remove, append, update, fields } = useFieldArray<AvailabilityFormValues, "dateOverrides">({
name: "dateOverrides",
});
const excludedDates = fields.map((field) => dayjs(field.ranges[0].start).utc().format("YYYY-MM-DD"));
const { t } = useLocale();
return (
<div className="p-6">
@ -70,7 +71,7 @@ const DateOverride = ({ workingHours }: { workingHours: WorkingHours[] }) => {
<p className="text-subtle mb-4 text-sm">{t("date_overrides_subtitle")}</p>
<div className="space-y-2">
<DateOverrideList
excludedDates={fields.map((field) => yyyymmdd(field.ranges[0].start))}
excludedDates={excludedDates}
remove={remove}
update={update}
items={fields}
@ -78,7 +79,7 @@ const DateOverride = ({ workingHours }: { workingHours: WorkingHours[] }) => {
/>
<DateOverrideInputDialog
workingHours={workingHours}
excludedDates={fields.map((field) => yyyymmdd(field.ranges[0].start))}
excludedDates={excludedDates}
onChange={(ranges) => append({ ranges })}
Trigger={
<Button color="secondary" StartIcon={Plus} data-testid="add-override">

View File

@ -43,13 +43,13 @@ const DateOverrideForm = ({
const { t, i18n, isLocaleReady } = useLocale();
const [datesUnavailable, setDatesUnavailable] = useState(
value &&
value[0].start.getHours() === 0 &&
value[0].start.getMinutes() === 0 &&
value[0].end.getHours() === 0 &&
value[0].end.getMinutes() === 0
value[0].start.getUTCHours() === 0 &&
value[0].start.getUTCMinutes() === 0 &&
value[0].end.getUTCHours() === 0 &&
value[0].end.getUTCMinutes() === 0
);
const [date, setDate] = useState<Dayjs | null>(value ? dayjs(value[0].start) : null);
const [date, setDate] = useState<Dayjs | null>(value ? dayjs.utc(value[0].start) : null);
const includedDates = useMemo(
() =>
workingHours
@ -110,8 +110,8 @@ const DateOverrideForm = ({
]
: values.range
).map((item) => ({
start: date.hour(item.start.getHours()).minute(item.start.getMinutes()).toDate(),
end: date.hour(item.end.getHours()).minute(item.end.getMinutes()).toDate(),
start: date.hour(item.start.getUTCHours()).minute(item.start.getUTCMinutes()).utc(true).toDate(),
end: date.hour(item.end.getUTCHours()).minute(item.end.getUTCMinutes()).utc(true).toDate(),
}))
);
onClose();

View File

@ -62,6 +62,7 @@ const DateOverrideList = ({
weekday: "short",
month: "long",
day: "numeric",
timeZone: "UTC",
}).format(item.ranges[0].start)}
</h3>
{item.ranges[0].start.valueOf() - item.ranges[0].end.valueOf() === 0 ? (