week numbers

This commit is contained in:
2024-09-30 21:44:05 -06:00
parent fb57aaa6b7
commit 73a05debfc
4 changed files with 97 additions and 7 deletions

View File

@@ -1,8 +1,10 @@
"use client";
import { CalendarMonthModel } from "./calendarMonthUtils";
import { CalendarMonthModel, getWeekNumber } from "./calendarMonthUtils";
import { DayOfWeek } from "@/models/local/localCourse";
import Day from "./day/Day";
import { Expandable } from "@/components/Expandable";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { getDateFromStringOrThrow } from "@/models/local/timeUtils";
export const CalendarMonth = ({ month }: { month: CalendarMonthModel }) => {
const weekInMilliseconds = 604_800_000;
@@ -35,7 +37,7 @@ export const CalendarMonth = ({ month }: { month: CalendarMonthModel }) => {
</div>
)}
>
<div className="grid grid-cols-7 text-center fw-bold">
<div className="grid grid-cols-7 text-center fw-bold ms-3">
{weekDaysList.map((day) => (
<div key={day} className={""}>
{day}
@@ -58,11 +60,26 @@ function CalendarWeek({
week: string[]; //date strings
monthNumber: number;
}) {
const { data: settings } = useLocalCourseSettingsQuery();
const startDate = getDateFromStringOrThrow(
settings.startDate,
"week calculation start date"
);
const firstDateString = getDateFromStringOrThrow(
week[0],
"week calculation first day of week"
);
const weekNumber = getWeekNumber(startDate, firstDateString);
return (
<div className="grid grid-cols-7">
{week.map((day, dayIndex) => (
<Day key={dayIndex} day={day} month={monthNumber} />
))}
<div className="flex flex-row">
<div className="my-auto text-gray-400">
{weekNumber.toString().padStart(2, "0")}
</div>
<div className="grid grid-cols-7 grow">
{week.map((day, dayIndex) => (
<Day key={dayIndex} day={day} month={monthNumber} />
))}
</div>
</div>
);
}

View File

@@ -37,7 +37,9 @@ function createCalendarMonth(year: number, month: number): CalendarMonthModel {
new Date(year, month - 1, dayIndex - firstDayOfMonth + 1, 12, 0, 0)
);
} else if (currentDay <= daysInMonth) {
return dateToMarkdownString(new Date(year, month - 1, currentDay++, 12, 0, 0));
return dateToMarkdownString(
new Date(year, month - 1, currentDay++, 12, 0, 0)
);
} else {
currentDay++;
return dateToMarkdownString(
@@ -74,3 +76,27 @@ export function getMonthsBetweenDates(
return createCalendarMonth(year, month);
});
}
export const getWeekNumber = (startDate: Date, currentDate: Date) => {
const sundayBeforeStartDate = getPreviousSunday(startDate);
const daysBetween = daysBetweenDates(sundayBeforeStartDate, currentDate);
const weeksDiff = Math.floor(daysBetween / 7);
if (weeksDiff >= 0) return weeksDiff + 1;
return weeksDiff;
};
const daysBetweenDates = (startDate: Date, endDate: Date) => {
const diffInTime = endDate.getTime() - startDate.getTime();
const diffInDays = diffInTime / (1000 * 3600 * 24);
return Math.floor(diffInDays);
};
const getPreviousSunday = (date: Date) => {
const result = new Date(date);
const dayOfWeek = result.getDay();
result.setDate(result.getDate() - dayOfWeek);
return result;
};

View File

@@ -0,0 +1,47 @@
import { describe, expect, it } from "vitest";
import { getWeekNumber } from "./calendarMonthUtils";
// months are 0 based, days are 1 based
describe("testing week numbers", () => {
it("can get before first day", () => {
const startDate = new Date(2024, 8, 3);
const firstDayOfFirstWeek = new Date(2024, 8, 1);
const weekNumber = getWeekNumber(startDate, firstDayOfFirstWeek);
expect(weekNumber).toBe(1);
});
it("can get end of first week", () => {
const startDate = new Date(2024, 8, 3);
const firstDayOfFirstWeek = new Date(2024, 8, 7);
const weekNumber = getWeekNumber(startDate, firstDayOfFirstWeek);
expect(weekNumber).toBe(1);
});
it("can get start of second week", () => {
const startDate = new Date(2024, 8, 3);
const firstDayOfFirstWeek = new Date(2024, 8, 8);
const weekNumber = getWeekNumber(startDate, firstDayOfFirstWeek);
expect(weekNumber).toBe(2);
});
it("can get start of third week", () => {
const startDate = new Date(2024, 8, 3);
const firstDayOfFirstWeek = new Date(2024, 8, 15);
const weekNumber = getWeekNumber(startDate, firstDayOfFirstWeek);
expect(weekNumber).toBe(3);
});
it("can get previous week", () => {
const startDate = new Date(2024, 8, 3);
const firstDayOfFirstWeek = new Date(2024, 7, 29);
const weekNumber = getWeekNumber(startDate, firstDayOfFirstWeek);
expect(weekNumber).toBe(-1);
});
});