// Helper function for date formatting and validation
export function formatDate(dateStr: string | null, format: 'full' | 'date-only' = 'full'): string {
if (!dateStr) return 'No date set';
try {
const date = new Date(dateStr);
if (isNaN(date.getTime())) return 'Invalid date';
if (format === 'date-only') {
return date.toLocaleDateString(undefined, {
year: 'numeric',
month: '2-digit',
day: '2-digit'
});
}
return date.toLocaleString(undefined, {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
timeZoneName: 'short'
});
} catch (error) {
return 'Invalid date';
}
}
// Helper function to parse and validate date strings
export function parseDate(dateStr: string | null): Date | null {
if (!dateStr) return null;
try {
// If the date string is just YYYY-MM-DD, treat it as local timezone
if (dateStr.match(/^\d{4}-\d{2}-\d{2}$/)) {
const [year, month, day] = dateStr.split('-').map(Number);
const date = new Date(year, month - 1, day);
return isNaN(date.getTime()) ? null : date;
}
// Otherwise parse as ISO string
const date = new Date(dateStr);
return isNaN(date.getTime()) ? null : date;
} catch {
return null;
}
}
// Helper function to check if a date is within a range
export function isDateInRange(date: string | null, before?: string, after?: string): boolean {
if (!date) return true; // Include assignments with no due date
const dueDate = parseDate(date);
if (!dueDate) return true; // Include if date parsing fails
if (before) {
const beforeDate = parseDate(before);
if (beforeDate) {
// Set to end of day (23:59:59.999) in local timezone
beforeDate.setHours(23, 59, 59, 999);
if (dueDate.getTime() > beforeDate.getTime()) return false;
}
}
if (after) {
const afterDate = parseDate(after);
if (afterDate) {
// Set to start of day (00:00:00.000) in local timezone
afterDate.setHours(0, 0, 0, 0);
if (dueDate.getTime() < afterDate.getTime()) return false;
}
}
return true;
}