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
This commit is contained in:
Alex van Andel
2023-07-12 17:32:11 -07:00
committed by GitHub
parent 9b37d65503
commit 605f7d35ec
3 changed files with 12 additions and 10 deletions
+4 -3
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">
@@ -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();
@@ -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 ? (