Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 10x 2x 2x 2x 10x 10x 10x 10x 10x 10x 31x 185x 152x 152x 125x 27x 31x 72x 55x 72x 72x 53x 31x 172x 83x 83x 83x 54x 29x 89x 89x 178x 155x 155x 89x 89x 89x 64x 25x 21x 18x 2x 2x 2x 2x 2x 2x 31x 67x 2x 2x 2x | // src/utils/dateUtils.ts
import { parseISO, format, isValid, differenceInDays } from 'date-fns';
/**
* Calculates the current year and a simplified week number.
*
* Note: This is a simple calculation where week 1 starts on January 1st.
* For true ISO 8601 week numbers (where week 1 is the first week with a Thursday),
* a dedicated library like `date-fns` (`getISOWeek` and `getISOWeekYear`) is recommended.
*
* @param date The date to calculate the simple week for. Defaults to the current date.
* @returns An object containing the year and week number.
*/
export function calculateSimpleWeekAndYear(date: Date = new Date()): { year: number; week: number } {
const year = date.getFullYear();
// Use UTC dates to calculate the difference in days.
// This avoids issues with Daylight Saving Time (DST) where a day might have 23 or 25 hours,
// which can cause the millisecond-based calculation to be slightly off (e.g., 149.96 days).
const startOfYear = Date.UTC(year, 0, 1);
const current = Date.UTC(year, date.getMonth(), date.getDate());
const msPerDay = 1000 * 60 * 60 * 24;
const dayOfYear = (current - startOfYear) / msPerDay;
// Divide by 7, take the floor to get the zero-based week, and add 1 for a one-based week number.
const week = Math.floor(dayOfYear / 7) + 1;
return { year, week };
}
export const formatShortDate = (dateString: string | null | undefined): string | null => {
if (!dateString) return null;
// Using `parseISO` from date-fns is more reliable than `new Date()` for YYYY-MM-DD strings.
// It correctly interprets the string as a local date, avoiding timezone-related "off-by-one" errors.
const date = parseISO(dateString);
if (isValid(date)) {
return format(date, 'MMM d');
}
return null;
};
export const calculateDaysBetween = (
startDate: string | Date | null | undefined,
endDate: string | Date | null | undefined,
): number | null => {
if (!startDate || !endDate) return null;
const start = typeof startDate === 'string' ? parseISO(startDate) : startDate;
const end = typeof endDate === 'string' ? parseISO(endDate) : endDate;
if (!isValid(start) || !isValid(end)) return null;
return differenceInDays(end, start);
};
interface DateRangeOptions {
verbose?: boolean;
}
export const formatDateRange = (
startDate: string | null | undefined,
endDate: string | null | undefined,
options?: DateRangeOptions,
): string | null => {
if (!options?.verbose) {
const start = formatShortDate(startDate);
const end = formatShortDate(endDate);
if (start && end) {
return start === end ? start : `${start} - ${end}`;
}
return start || end || null;
}
// Verbose format logic
const dateFormat = 'MMMM d, yyyy';
const formatFn = (dateStr: string | null | undefined) => {
if (!dateStr) return null;
const date = parseISO(dateStr);
return isValid(date) ? format(date, dateFormat) : null;
};
const start = formatFn(startDate);
const end = formatFn(endDate);
if (start && end) {
return start === end ? `Valid on ${start}` : `Deals valid from ${start} to ${end}`;
}
if (start) return `Deals start ${start}`;
if (end) return `Deals end ${end}`;
return null;
};
/**
* Returns the current date as an ISO 8601 string (YYYY-MM-DD).
* Useful for getting "today" without the time component.
*/
export const getCurrentDateISOString = (): string => {
return format(new Date(), 'yyyy-MM-dd');
};
export { calculateSimpleWeekAndYear as getSimpleWeekAndYear };
|