Skip to content

Commit

Permalink
fix: utc times in scheduler (#136)
Browse files Browse the repository at this point in the history
  • Loading branch information
invertedEcho authored Nov 17, 2024
1 parent 117002b commit 8aef480
Showing 1 changed file with 35 additions and 31 deletions.
66 changes: 35 additions & 31 deletions backend/src/utils/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,47 @@ import { DefaultPostgresInterval } from './interval';

// TODO: this will only work for UTC+2, overall we need to add a local time zone in the recurring task group and do all the stuff dynamic.
export function getStartOfInterval(interval: DefaultPostgresInterval): Date {
//HOTFIX: This seems very hacky. We should think of something more elegant to handle this in the future, also consider the case when
// HOTFIX: This seems very hacky. We should think of something more elegant to handle this in the future, also consider the case when
// assignment scheduler runs during the changing days of DST.
// Function to check if the current date is in the DST period (from last Sunday in March to last Sunday in October)
const isDSTPeriod = (date: Date) => {
const year = date.getFullYear();
const lastSundayInMarch = new Date(year, 2, 31); // Start from March 31
lastSundayInMarch.setDate(
lastSundayInMarch.getDate() - lastSundayInMarch.getDay(),
); // Find the last Sunday in March
const lastSundayInOctober = new Date(year, 9, 31); // Start from October 31
lastSundayInOctober.setDate(
lastSundayInOctober.getDate() - lastSundayInOctober.getDay(),
); // Find the last Sunday in October
return date >= lastSundayInMarch && date < lastSundayInOctober;
};

// Determine target hour based on whether it's DST period
const targetHour = isDSTPeriod(new Date()) ? 22 : 23; // 22:00 during DST, 23:00 afterward
const targetHour = getIsDSTPeroid(new Date()) ? 22 : 23; // 22:00 during DST, 23:00 afterward

switch (interval) {
// Go back to previous day at the calculated target hour
case '1 day': {
const todayTargetTime = new Date();
todayTargetTime.setHours(targetHour, 0, 0, 0); // Set to target hour (22 or 23 based on DST)
todayTargetTime.setUTCHours(targetHour, 0, 0, 0); // Set to target hour (22 or 23 based on DST)

// Go back to previous day
return new Date(todayTargetTime.setDate(todayTargetTime.getDate() - 1));
return new Date(
todayTargetTime.setUTCDate(todayTargetTime.getUTCDate() - 1),
);
}

// Go back to previous Sunday at the calculated target hour
case '7 days': {
const now = new Date();
const todayTargetTime = new Date(now);
todayTargetTime.setHours(targetHour, 0, 0, 0); // Set to target hour (22 or 23 based on DST)
todayTargetTime.setUTCHours(targetHour, 0, 0, 0); // Set to target hour (22 or 23 based on DST)

if (now.getDay() === 0 && now.getTime() >= todayTargetTime.getTime()) {
if (now.getUTCDay() === 0 && now.getTime() >= todayTargetTime.getTime()) {
// If it's Sunday and past target hour, return today at the target hour
return todayTargetTime;
} else {
// Otherwise, find the previous Sunday at target hour
const previousSundayTargetTime = new Date(todayTargetTime);
const daysSinceSunday = (now.getDay() + 7) % 7;
previousSundayTargetTime.setDate(
previousSundayTargetTime.getDate() - daysSinceSunday,
const daysSinceSunday = (now.getUTCDay() + 7) % 7;
previousSundayTargetTime.setUTCDate(
previousSundayTargetTime.getUTCDate() - daysSinceSunday,
);

if (now.getDay() === 0 && now.getTime() < todayTargetTime.getTime()) {
if (
now.getUTCDay() === 0 &&
now.getTime() < todayTargetTime.getTime()
) {
// If it's Sunday but before target hour, go back to the previous Sunday
previousSundayTargetTime.setDate(
previousSundayTargetTime.getDate() - 7,
previousSundayTargetTime.setUTCDate(
previousSundayTargetTime.getUTCDate() - 7,
);
}

Expand All @@ -64,15 +55,15 @@ export function getStartOfInterval(interval: DefaultPostgresInterval): Date {
case '1 mon':
const now = new Date();
const firstDayOfCurrentMonth = new Date(
now.getFullYear(),
now.getMonth(),
now.getUTCFullYear(),
now.getUTCMonth(),
1,
);
const dayBeforeFirstDayOfCurrentMonth = new Date(firstDayOfCurrentMonth);
dayBeforeFirstDayOfCurrentMonth.setDate(
dayBeforeFirstDayOfCurrentMonth.getDate() - 1,
dayBeforeFirstDayOfCurrentMonth.setUTCDate(
dayBeforeFirstDayOfCurrentMonth.getUTCDate() - 1,
);
dayBeforeFirstDayOfCurrentMonth.setHours(targetHour, 0, 0, 0); // Set to target hour (22 or 23 based on DST)
dayBeforeFirstDayOfCurrentMonth.setUTCHours(targetHour, 0, 0, 0); // Set to target hour (22 or 23 based on DST)
return dayBeforeFirstDayOfCurrentMonth;
}
}
Expand All @@ -82,3 +73,16 @@ export function addDays(date: Date, days: number) {
newDate.setUTCDate(date.getUTCDate() + days);
return newDate;
}

export function getIsDSTPeroid(date: Date) {
const year = date.getFullYear();
const lastSundayInMarch = new Date(year, 2, 31);
lastSundayInMarch.setUTCDate(
lastSundayInMarch.getDate() - lastSundayInMarch.getDay(),
);
const lastSundayInOctober = new Date(year, 9, 31);
lastSundayInOctober.setUTCDate(
lastSundayInOctober.getDate() - lastSundayInOctober.getDay(),
);
return date >= lastSundayInMarch && date < lastSundayInOctober;
}

0 comments on commit 8aef480

Please sign in to comment.