Skip to content

Commit

Permalink
adjust for different timezones
Browse files Browse the repository at this point in the history
  • Loading branch information
meetulr committed Feb 11, 2024
1 parent 0f3fd2f commit 4cac65e
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 42 deletions.
19 changes: 6 additions & 13 deletions src/helpers/event/createEventHelpers/createRecurringEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
createRecurrenceRule,
generateRecurringEventInstances,
} from "../recurringEventHelpers";
import { convertToUTCDate } from "../../../utilities/convertToUTCDate";

/**
* This function creates the instances of a recurring event upto a certain date.
Expand Down Expand Up @@ -49,20 +48,14 @@ export const createRecurringEvent = async (
data?.endDate
);

const convertedStartDate = convertToUTCDate(data.startDate);
let convertedEndDate = null;
if (data.endDate) {
convertedEndDate = convertToUTCDate(data.endDate);
}

// create a base recurring event first, based on which all the
// recurring instances would be dynamically generated
const baseRecurringEvent = await Event.create(
[
{
...data,
startDate: convertedStartDate,
endDate: convertedEndDate,
startDate: data.startDate,
endDate: data.endDate,
recurring: true,
isBaseRecurringEvent: true,
creatorId: currentUserId,
Expand All @@ -77,8 +70,8 @@ export const createRecurringEvent = async (
// to be generated in this operation (rest would be generated dynamically during query)
const recurringInstanceDates = getRecurringInstanceDates(
recurrenceRuleString,
convertedStartDate,
convertedEndDate
data.startDate,
data.endDate
);

// get the date for the latest created instance
Expand All @@ -87,8 +80,8 @@ export const createRecurringEvent = async (
// create a recurrenceRule document that would contain the recurrence pattern
const recurrenceRule = await createRecurrenceRule(
recurrenceRuleString,
convertedStartDate,
convertedEndDate,
data.startDate,
data.endDate,
organizationId.toString(),
baseRecurringEvent[0]?._id.toString(),
latestInstanceDate,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { format } from "date-fns";
import type { RecurrenceRuleInput } from "../../../types/generatedGraphQLTypes";
import { adjustForTimezoneOffset } from "../../../utilities/recurrenceDatesUtil";

/**
* This function generates the recurrence rule (rrule) string.
* @param recurrenceRuleData - the recurrenceRuleInput provided in the args.
* @param recurrenceStartDate - start date of recurrence.
* @param recurrenceEndDate - end date of recurrence.
* @remarks The following steps are followed:
* 1. Initiate an empty recurrenceRule string.
* 2. Add the recurrence rules one by one.
* 1. Adjust the start and end dates of recurrence for timezone offsets.
* 2. Get the recurrence rules and make a recurrenceRuleString.
* @returns The recurrence rule string that would be used to create a valid rrule object.
*/

Expand All @@ -17,21 +18,39 @@ export const generateRecurrenceRuleString = (
recurrenceStartDate: Date,
recurrenceEndDate?: Date
): string => {
// destructure the rules
const { frequency, count, weekDays } = recurrenceRuleData;
// adjust the dates according to the timezone offset
recurrenceStartDate = adjustForTimezoneOffset(recurrenceStartDate);
if (recurrenceEndDate) {
recurrenceEndDate = adjustForTimezoneOffset(recurrenceEndDate);
}

// recurrence start date
// (not necessarily the start date of the first recurring instance)
const formattedRecurrenceStartDate = format(
let formattedRecurrenceStartDate = format(
recurrenceStartDate,
"yyyyMMdd'T'HHmmss'Z'"
);

// format it to be UTC midnight
formattedRecurrenceStartDate = formattedRecurrenceStartDate.replace(
/T\d{6}Z/,
"T000000Z"
);

// date upto which instances would be generated
const formattedRecurrenceEndDate = recurrenceEndDate
let formattedRecurrenceEndDate = recurrenceEndDate
? format(recurrenceEndDate, "yyyyMMdd'T'HHmmss'Z'")
: "";

// format it to be UTC midnight
formattedRecurrenceEndDate = formattedRecurrenceEndDate.replace(
/T\d{6}Z/,
"T000000Z"
);

// destructure the recurrence rules
const { frequency, count, weekDays } = recurrenceRuleData;

// string representing the days of the week the event would recur
const weekDaysString = weekDays?.length ? weekDays.join(",") : "";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type mongoose from "mongoose";
import { format } from "date-fns";
import type { InterfaceEvent } from "../../../models";
import { Event, EventAttendee, User } from "../../../models";
import type { EventInput } from "../../../types/generatedGraphQLTypes";
Expand Down Expand Up @@ -51,12 +50,10 @@ export const generateRecurringEventInstances = async ({
}: InterfaceGenerateRecurringInstances): Promise<InterfaceEvent> => {
const recurringInstances: InterfaceRecurringEvent[] = [];
recurringInstanceDates.map((date) => {
const formattedInstanceDate = format(date, "yyyy-MM-dd");

const createdEventInstance = {
...data,
startDate: formattedInstanceDate,
endDate: formattedInstanceDate,
startDate: date,
endDate: date,
recurring: true,
isBaseRecurringEvent: false,
recurrenceRuleId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
* @param calendarDate - the calendar date (To be used for dynamic instance generation during queries).
* @remarks The following steps are followed:
* 1. Get the date limit for instance generation based on its recurrence frequency.
* 3. Get the dates for recurring instances.
* 2. Get the dates for recurring event instances.
* @returns Dates for recurring instances to be generated during this operation.
*/

Expand Down
12 changes: 11 additions & 1 deletion src/resolvers/Mutation/createEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,13 @@ export const createEvent: MutationResolvers["createEvent"] = async (
);
}

/* c8 ignore start */
if (session) {
// start a transaction
session.startTransaction();
}

/* c8 ignore stop */
try {
let createdEvent: InterfaceEvent;

Expand All @@ -151,16 +154,23 @@ export const createEvent: MutationResolvers["createEvent"] = async (
);
}

/* c8 ignore start */
if (session) {
// commit transaction if everything's successful
await session.commitTransaction();
}

// Returns the createdEvent.
/* c8 ignore stop */
return createdEvent;
} catch (error) {
/* c8 ignore start */
if (session) {
// abort transaction if something fails
await session.abortTransaction();
}

throw error;
}

/* c8 ignore stop */
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,20 @@ export const convertToUTCDate = (date: Date): Date => {

return utcMidnight;
};

/**
* This function adjusts for the timezone offset.
* @param date - the date to be adjusted.
* @returns adjusted date.
*/
export const adjustForTimezoneOffset = (date: Date): Date => {
const timeZoneOffset = new Date().getTimezoneOffset();

/* c8 ignore start */
if (timeZoneOffset > 0) {
date = new Date(date.getTime() + timeZoneOffset * 60 * 1000);
}

/* c8 ignore stop */
return date;
};
Loading

0 comments on commit 4cac65e

Please sign in to comment.