From 9ba13a3f3cf5aa0a3a979c293b63019afd2edaf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efra=C3=ADn=20Roch=C3=ADn?= Date: Fri, 17 Mar 2023 04:53:05 -0700 Subject: [PATCH] Amend logic to calc slots time already in DST (#7792) * amend logic to calculate DST time on buildSlots * send start and end date in UTC * port the logic to calc DST from buildSlots to inWithinAvailableHours --- .../web/components/booking/pages/BookingPage.tsx | 8 ++++---- .../features/bookings/lib/handleNewBooking.ts | 11 ++++------- packages/lib/slots.ts | 16 +++++++--------- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/apps/web/components/booking/pages/BookingPage.tsx b/apps/web/components/booking/pages/BookingPage.tsx index 8aa1573d83..92346c5716 100644 --- a/apps/web/components/booking/pages/BookingPage.tsx +++ b/apps/web/components/booking/pages/BookingPage.tsx @@ -448,8 +448,8 @@ const BookingPage = ({ const recurringEventId = uuidv4(); const recurringBookings = recurringDates.map((recurringDate) => ({ ...bookingValues, - start: dayjs(recurringDate).format(), - end: dayjs(recurringDate).add(duration, "minute").format(), + start: dayjs(recurringDate).utc().format(), + end: dayjs(recurringDate).utc().add(duration, "minute").format(), eventTypeId: eventType.id, eventTypeSlug: eventType.slug, recurringEventId, @@ -468,8 +468,8 @@ const BookingPage = ({ } else { mutation.mutate({ ...bookingValues, - start: dayjs(date).tz(timeZone()).format(), - end: dayjs(date).tz(timeZone()).add(duration, "minute").format(), + start: dayjs(date).utc().format(), + end: dayjs(date).utc().add(duration, "minute").format(), eventTypeId: eventType.id, eventTypeSlug: eventType.slug, timeZone: timeZone(), diff --git a/packages/features/bookings/lib/handleNewBooking.ts b/packages/features/bookings/lib/handleNewBooking.ts index 89e7f82dcb..2e5744dcb6 100644 --- a/packages/features/bookings/lib/handleNewBooking.ts +++ b/packages/features/bookings/lib/handleNewBooking.ts @@ -38,7 +38,6 @@ import { deleteScheduledSMSReminder } from "@calcom/features/ee/workflows/lib/re import getWebhooks from "@calcom/features/webhooks/lib/getWebhooks"; import { isPrismaObjOrUndefined, parseRecurringEvent } from "@calcom/lib"; import { getVideoCallUrl } from "@calcom/lib/CalEventParser"; -import { getDSTDifference, isInDST } from "@calcom/lib/date-fns"; import { getDefaultEvent, getGroupName, getUsernameList } from "@calcom/lib/defaultEvents"; import { getErrorFromUnknown } from "@calcom/lib/errors"; import getPaymentAppData from "@calcom/lib/getPaymentAppData"; @@ -125,13 +124,11 @@ const isWithinAvailableHours = ( ) => { const timeSlotStart = dayjs(timeSlot.start).utc(); const timeSlotEnd = dayjs(timeSlot.end).utc(); - const isOrganizerInDSTWhenSlotStart = isInDST(timeSlotStart.tz(organizerTimeZone)); - const organizerDSTDifference = getDSTDifference(organizerTimeZone); + const organizerDSTDiff = + dayjs().tz(organizerTimeZone).utcOffset() - timeSlotStart.tz(organizerTimeZone).utcOffset(); + const getTime = (slotTime: Dayjs, minutes: number) => + slotTime.startOf("day").add(minutes + organizerDSTDiff, "minutes"); - const getTime = (slotTime: Dayjs, minutes: number) => { - const minutesDTS = isOrganizerInDSTWhenSlotStart ? minutes - organizerDSTDifference : minutes; - return slotTime.startOf("day").add(minutesDTS, "minutes"); - }; for (const workingHour of workingHours) { const startTime = getTime(timeSlotStart, workingHour.startTime); const endTime = getTime(timeSlotEnd, workingHour.endTime); diff --git a/packages/lib/slots.ts b/packages/lib/slots.ts index 57cf50112b..3ec13df18b 100644 --- a/packages/lib/slots.ts +++ b/packages/lib/slots.ts @@ -3,7 +3,7 @@ import dayjs from "@calcom/dayjs"; import type { WorkingHours, TimeRange as DateOverride } from "@calcom/types/schedule"; import { getWorkingHours } from "./availability"; -import { getTimeZone, isInDST, getDSTDifference } from "./date-fns"; +import { getTimeZone } from "./date-fns"; export type GetSlots = { inviteeDate: Dayjs; @@ -99,15 +99,13 @@ function buildSlots({ } } - const isOrganizerInDST = isInDST(startOfInviteeDay.tz(organizerTimeZone)); - const isInviteeInDST = isInDST(startOfInviteeDay.tz(inviteeTimeZone)); - const organizerDSTDifference = getDSTDifference(organizerTimeZone); - const inviteeDSTDifference = getDSTDifference(inviteeTimeZone); - + const organizerDSTDiff = + dayjs().tz(organizerTimeZone).utcOffset() - startOfInviteeDay.tz(organizerTimeZone).utcOffset(); + const inviteeDSTDiff = + dayjs().tz(inviteeTimeZone).utcOffset() - startOfInviteeDay.tz(inviteeTimeZone).utcOffset(); const slots: { time: Dayjs; userIds?: number[] }[] = []; - const resultDSTDifference = isOrganizerInDST ? organizerDSTDifference : -inviteeDSTDifference; const getTime = (time: number) => { - const minutes = isOrganizerInDST !== isInviteeInDST ? time - resultDSTDifference : time; + const minutes = time + organizerDSTDiff - inviteeDSTDiff; return startOfInviteeDay.tz(inviteeTimeZone).add(minutes, "minutes"); }; @@ -152,7 +150,7 @@ const getSlots = ({ // checks if the start date is in the past /** - * TODO: change "day" for "hour" to stop displaying 1 day before today + * TODO: change "day" for "hour" to stop displaying 1 day before today * This is displaying a day as available as sometimes difference between two dates is < 24 hrs. * But when doing timezones an available day for an owner can be 2 days available in other users tz. *