Bugfix/5271 wrong availability displayed on nov 6 (#5365)

* Fixes the localisation issue with recurring events

* Implement DST as Dayjs doesn't

* Fixed generated booking URL when different TZ is set

* manually apply DST offset to times

* Fix type error
This commit is contained in:
Alex van Andel authored and GitHub committed 2022-11-04 10:59:38 -04:00
1 parent 328a354f4d
commit db9911a264
4 files changed
+37 -33

No files matched your search

@@ -83,7 +83,7 @@ const AvailableTimes: FC<AvailableTimesProps> = ({
pathname: router.pathname.endsWith("/embed") ? "../book" : "book",
query: {
...router.query,
date: dayjs(slot.time).format(),
date: dayjs.utc(slot.time).tz(timeZone()).format(),
type: eventTypeId,
slug: eventTypeSlug,
/** Treat as recurring only when a count exist and it's not a rescheduling workflow */
@@ -497,26 +497,17 @@ const BookingPage = ({
<div className="text-bookinghighlight flex items-start text-sm">
<Icon.FiCalendar className="mr-[10px] ml-[2px] mt-[2px] inline-block h-4 w-4" />
<div className="text-sm font-medium">
{(rescheduleUid || !eventType.recurringEvent?.freq) &&
`${formatTime(dayjs(date).toDate(), user?.timeFormat, user?.timeZone)}, ${dayjs(
date
).format("dddd, D MMMM YYYY")}`}
{(rescheduleUid || !eventType.recurringEvent?.freq) && `${parseDate(date, i18n)}`}
{!rescheduleUid &&
eventType.recurringEvent?.freq &&
recurringDates.slice(0, 5).map((aDate, key) => {
return (
<p key={key}>{`${formatTime(aDate, user?.timeFormat, user?.timeZone)}, ${dayjs(
aDate
).format("dddd, D MMMM YYYY")}`}</p>
);
recurringStrings.slice(0, 5).map((timeFormatted, key) => {
return <p key={key}>{timeFormatted}</p>;
})}
{!rescheduleUid && eventType.recurringEvent?.freq && recurringStrings.length > 5 && (
<div className="flex">
<Tooltip
content={recurringDates.slice(5).map((aDate, key) => (
<p key={key}>{`${formatTime(aDate, user?.timeFormat, user?.timeZone)}, ${dayjs(
aDate
).format("dddd, D MMMM YYYY")}`}</p>
content={recurringStrings.slice(5).map((timeFormatted, key) => (
<p key={key}>{timeFormatted}</p>
))}>
<p className="dark:text-darkgray-600 text-sm">
{t("plus_more", { count: recurringStrings.length - 5 })}
+13 -17
View File
@@ -20,15 +20,6 @@ export const parseDate = (date: string | null | Dayjs, i18n: I18n) => {
return processDate(date, i18n);
};
// tzid is currently broken in rrule library.
// @see https://github.com/jakubroztocil/rrule/issues/523
const dateWithZone = (d: Date, timeZone?: string) => {
const dateInLocalTZ = new Date(d.toLocaleString("en-US", { timeZone: "UTC" }));
const dateInTargetTZ = new Date(d.toLocaleString("en-US", { timeZone: timeZone || "UTC" }));
const tzOffset = dateInTargetTZ.getTime() - dateInLocalTZ.getTime();
return new Date(d.getTime() - tzOffset);
};
export const parseRecurringDates = (
{
startDate,
@@ -48,16 +39,21 @@ export const parseRecurringDates = (
const rule = new RRule({
...restRecurringEvent,
count: recurringCount,
dtstart: dayjs(startDate).utc(true).toDate(),
});
// UTC times with tzOffset applied to account for DST
const times = rule.all().map((t) => dateWithZone(t, timeZone));
const dateStrings = times.map((t) => {
// undo DST diffs for localized display.
return processDate(dayjs.utc(t).tz(timeZone), i18n);
dtstart: new Date(dayjs(startDate).valueOf()),
});
return [dateStrings, times];
const startUtcOffset = dayjs(startDate).utcOffset();
// UTC still need to have DST applied, rrule does not do this.
const times = rule.all().map((t) => {
// applying the DST offset.
return dayjs.utc(t).add(startUtcOffset - dayjs(t).utcOffset(), "minute");
});
const dateStrings = times.map((t) => {
// finally; show in local timeZone again
return processDate(t.tz(timeZone), i18n);
});
return [dateStrings, times.map((t) => t.toDate())];
};
export const extractRecurringDates = (