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:
@@ -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`;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user