refactor: unify date handling with utility functions

- Replaced direct date manipulations with utility functions like `getToday`, `parseDate`, and `createDateFromParts` across various components and services for consistency.
- Updated date initialization in `JiraAnalyticsService`, `BackupService`, and `DailyClient` to improve clarity and maintainability.
- Enhanced date parsing in forms and API routes to ensure proper handling of date strings.
This commit is contained in:
Julien Froidefond
2025-09-21 13:04:34 +02:00
parent c3c1d24fa2
commit 4ba6ba2c0b
23 changed files with 117 additions and 68 deletions

View File

@@ -3,7 +3,7 @@ import { exec } from 'child_process';
import { promisify } from 'util';
import path from 'path';
import { createHash } from 'crypto';
import { formatDateForDisplay, getToday } from './date-utils';
import { formatDateForDisplay, getToday, parseDate } from './date-utils';
const execAsync = promisify(exec);
@@ -160,7 +160,7 @@ export class BackupUtils {
// Format: 2025-09-18T14-12-05-737Z -> 2025-09-18T14:12:05.737Z
const isoString = dateMatch[2]
.replace(/T(\d{2})-(\d{2})-(\d{2})-(\d{3})Z/, 'T$1:$2:$3.$4Z');
date = new Date(isoString);
date = parseDate(isoString);
}
return { type, date };
@@ -170,7 +170,7 @@ export class BackupUtils {
* Génère un nom de fichier de backup
*/
static generateBackupFilename(type: 'manual' | 'automatic'): string {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const timestamp = getToday().toISOString().replace(/[:.]/g, '-');
return `towercontrol_${type}_${timestamp}.db`;
}

View File

@@ -117,6 +117,28 @@ export function createDate(date: Date): Date {
return new Date(date);
}
/**
* Crée une date à partir de composants année/mois/jour
*/
export function createDateFromParts(year: number, month: number, day: number): Date {
return new Date(year, month - 1, day); // month est 0-indexé en JavaScript
}
/**
* Convertit une date pour un input datetime-local (gestion timezone)
*/
export function formatDateForDateTimeInput(date: Date): string {
const adjustedDate = new Date(date.getTime() - date.getTimezoneOffset() * 60000);
return adjustedDate.toISOString().slice(0, 16);
}
/**
* Parse une valeur d'input datetime-local vers une Date
*/
export function parseDateTimeInput(value: string): Date {
return new Date(value);
}
/**
* Ajoute des jours à une date
*/
@@ -126,6 +148,15 @@ export function addDays(date: Date, days: number): Date {
return result;
}
/**
* Ajoute des minutes à une date
*/
export function addMinutes(date: Date, minutes: number): Date {
const result = createDate(date);
result.setMinutes(result.getMinutes() + minutes);
return result;
}
/**
* Soustrait des jours à une date
*/

View File

@@ -1,4 +1,5 @@
import { JiraAnalytics } from './types';
import { getToday, subtractDays, parseDate } from './date-utils';
export type PeriodFilter = '7d' | '30d' | '3m' | 'current';
@@ -9,18 +10,18 @@ export function filterAnalyticsByPeriod(
analytics: JiraAnalytics,
period: PeriodFilter
): JiraAnalytics {
const now = new Date();
const now = getToday();
let cutoffDate: Date;
switch (period) {
case '7d':
cutoffDate = new Date(now.getTime() - (7 * 24 * 60 * 60 * 1000));
cutoffDate = subtractDays(now, 7);
break;
case '30d':
cutoffDate = new Date(now.getTime() - (30 * 24 * 60 * 60 * 1000));
cutoffDate = subtractDays(now, 30);
break;
case '3m':
cutoffDate = new Date(now.getTime() - (90 * 24 * 60 * 60 * 1000));
cutoffDate = subtractDays(now, 90);
break;
case 'current':
default:
@@ -56,7 +57,7 @@ function filterCurrentSprintAnalytics(analytics: JiraAnalytics): JiraAnalytics {
function filterAnalyticsByDate(analytics: JiraAnalytics, cutoffDate: Date): JiraAnalytics {
// Filtrer l'historique des sprints
const filteredSprintHistory = analytics.velocityMetrics.sprintHistory.filter(sprint => {
const sprintEndDate = new Date(sprint.endDate);
const sprintEndDate = parseDate(sprint.endDate);
return sprintEndDate >= cutoffDate;
});

View File

@@ -151,22 +151,22 @@ function compareTasksByField(a: Task, b: Task, sortConfig: SortConfig): number {
case 'createdAt':
return compareValues(
new Date(a.createdAt).getTime(),
new Date(b.createdAt).getTime(),
a.createdAt.getTime(),
b.createdAt.getTime(),
direction
);
case 'updatedAt':
return compareValues(
new Date(a.updatedAt).getTime(),
new Date(b.updatedAt).getTime(),
a.updatedAt.getTime(),
b.updatedAt.getTime(),
direction
);
case 'dueDate':
return compareValues(
a.dueDate ? new Date(a.dueDate).getTime() : null,
b.dueDate ? new Date(b.dueDate).getTime() : null,
a.dueDate ? a.dueDate.getTime() : null,
b.dueDate ? b.dueDate.getTime() : null,
direction
);