feat : helpers purs de semaine ISO (#MUI-33)
This commit is contained in:
67
app/components/malio/date/composables/dateWeek.ts
Normal file
67
app/components/malio/date/composables/dateWeek.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import {formatIsoToDisplay} from './dateFormat'
|
||||
|
||||
const parseUtc = (iso: string): Date => {
|
||||
const [y, m, d] = iso.split('-').map(Number)
|
||||
return new Date(Date.UTC(y, m - 1, d))
|
||||
}
|
||||
|
||||
const toIso = (d: Date): string => {
|
||||
const y = d.getUTCFullYear()
|
||||
const m = String(d.getUTCMonth() + 1).padStart(2, '0')
|
||||
const day = String(d.getUTCDate()).padStart(2, '0')
|
||||
return `${y}-${m}-${day}`
|
||||
}
|
||||
|
||||
export function mondayOf(iso: string): string {
|
||||
const d = parseUtc(iso)
|
||||
const dayNum = d.getUTCDay() || 7 // dimanche = 7
|
||||
d.setUTCDate(d.getUTCDate() - (dayNum - 1))
|
||||
return toIso(d)
|
||||
}
|
||||
|
||||
export function sundayOf(iso: string): string {
|
||||
const d = parseUtc(mondayOf(iso))
|
||||
d.setUTCDate(d.getUTCDate() + 6)
|
||||
return toIso(d)
|
||||
}
|
||||
|
||||
export function toIsoWeek(iso: string): string {
|
||||
const d = parseUtc(iso)
|
||||
const dayNum = d.getUTCDay() || 7
|
||||
d.setUTCDate(d.getUTCDate() + 4 - dayNum) // jeudi de la semaine
|
||||
const isoYear = d.getUTCFullYear()
|
||||
const yearStart = new Date(Date.UTC(isoYear, 0, 1))
|
||||
const week = Math.ceil((((d.getTime() - yearStart.getTime()) / 86400000) + 1) / 7)
|
||||
return `${isoYear}-W${String(week).padStart(2, '0')}`
|
||||
}
|
||||
|
||||
export function isoWeekToMonday(week: string): string | null {
|
||||
const m = /^(\d{4})-W(\d{2})$/.exec(week)
|
||||
if (!m) return null
|
||||
const year = Number(m[1])
|
||||
const w = Number(m[2])
|
||||
if (w < 1 || w > 53) return null
|
||||
// Lundi de la semaine 1 = lundi de la semaine contenant le 4 janvier
|
||||
const jan4 = new Date(Date.UTC(year, 0, 4))
|
||||
const jan4Day = jan4.getUTCDay() || 7
|
||||
const monday = new Date(jan4)
|
||||
monday.setUTCDate(jan4.getUTCDate() - (jan4Day - 1) + (w - 1) * 7)
|
||||
const iso = toIso(monday)
|
||||
// Garde-fou : la semaine 53 n'existe pas pour toutes les années
|
||||
if (toIsoWeek(iso) !== week) return null
|
||||
return iso
|
||||
}
|
||||
|
||||
export function isValidIsoWeek(week: string): boolean {
|
||||
return isoWeekToMonday(week) !== null
|
||||
}
|
||||
|
||||
export function formatWeekDisplay(week: string): string {
|
||||
const monday = isoWeekToMonday(week)
|
||||
if (!monday) return ''
|
||||
const sunday = sundayOf(monday)
|
||||
const w = Number(week.slice(6))
|
||||
const startDdMm = formatIsoToDisplay(monday).slice(0, 5) // "18/05"
|
||||
const endFull = formatIsoToDisplay(sunday) // "24/05/2026"
|
||||
return `Semaine ${w} (${startDdMm} → ${endFull})`
|
||||
}
|
||||
Reference in New Issue
Block a user