feat : composable datetimeFormat pour MalioDateTime (#MUI-33)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
61
app/components/malio/date/composables/datetimeFormat.test.ts
Normal file
61
app/components/malio/date/composables/datetimeFormat.test.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import {describe, expect, it} from 'vitest'
|
||||
import {
|
||||
composeDateTime,
|
||||
formatIsoDateTimeToDisplay,
|
||||
isValidIsoDateTime,
|
||||
splitDateTime,
|
||||
} from './datetimeFormat'
|
||||
|
||||
describe('datetimeFormat', () => {
|
||||
describe('isValidIsoDateTime', () => {
|
||||
it('accepte un datetime ISO complet valide', () => {
|
||||
expect(isValidIsoDateTime('2026-05-20T14:30:00')).toBe(true)
|
||||
expect(isValidIsoDateTime('2026-01-01T00:00:00')).toBe(true)
|
||||
expect(isValidIsoDateTime('2026-12-31T23:59:59')).toBe(true)
|
||||
})
|
||||
|
||||
it('rejette une date seule, des composants invalides ou une chaîne vide', () => {
|
||||
expect(isValidIsoDateTime('2026-05-20')).toBe(false)
|
||||
expect(isValidIsoDateTime('2026-13-01T00:00:00')).toBe(false)
|
||||
expect(isValidIsoDateTime('2026-05-20T24:00:00')).toBe(false)
|
||||
expect(isValidIsoDateTime('2026-05-20T14:60:00')).toBe(false)
|
||||
expect(isValidIsoDateTime('2026-05-20T14:30:60')).toBe(false)
|
||||
expect(isValidIsoDateTime('2026-05-20T14:30')).toBe(false)
|
||||
expect(isValidIsoDateTime('')).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('formatIsoDateTimeToDisplay', () => {
|
||||
it('formate un datetime valide en JJ/MM/AAAA HH:MM', () => {
|
||||
expect(formatIsoDateTimeToDisplay('2026-05-20T14:30:00')).toBe('20/05/2026 14:30')
|
||||
})
|
||||
|
||||
it('renvoie une chaîne vide pour nul ou invalide', () => {
|
||||
expect(formatIsoDateTimeToDisplay(null)).toBe('')
|
||||
expect(formatIsoDateTimeToDisplay('2026-05-20')).toBe('')
|
||||
expect(formatIsoDateTimeToDisplay('nope')).toBe('')
|
||||
})
|
||||
})
|
||||
|
||||
describe('splitDateTime', () => {
|
||||
it('découpe un datetime valide', () => {
|
||||
expect(splitDateTime('2026-05-20T14:30:00')).toEqual({date: '2026-05-20', time: '14:30'})
|
||||
})
|
||||
|
||||
it('renvoie date null et time vide pour nul, date seule ou invalide', () => {
|
||||
expect(splitDateTime(null)).toEqual({date: null, time: ''})
|
||||
expect(splitDateTime('2026-05-20')).toEqual({date: null, time: ''})
|
||||
expect(splitDateTime('nope')).toEqual({date: null, time: ''})
|
||||
})
|
||||
})
|
||||
|
||||
describe('composeDateTime', () => {
|
||||
it('recompose un datetime ISO avec secondes à 00', () => {
|
||||
expect(composeDateTime('2026-05-20', '14:30')).toBe('2026-05-20T14:30:00')
|
||||
})
|
||||
|
||||
it('utilise 00:00 quand l\'heure est vide', () => {
|
||||
expect(composeDateTime('2026-05-20', '')).toBe('2026-05-20T00:00:00')
|
||||
})
|
||||
})
|
||||
})
|
||||
33
app/components/malio/date/composables/datetimeFormat.ts
Normal file
33
app/components/malio/date/composables/datetimeFormat.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import {isValidIso} from './dateFormat'
|
||||
|
||||
const DATETIME_RE = /^(\d{4}-\d{2}-\d{2})T(\d{2}):(\d{2}):(\d{2})$/
|
||||
|
||||
export function isValidIsoDateTime(s: string): boolean {
|
||||
const m = DATETIME_RE.exec(s)
|
||||
if (!m) return false
|
||||
const [, date, hh, mm, ss] = m
|
||||
if (!isValidIso(date)) return false
|
||||
const h = Number(hh)
|
||||
const min = Number(mm)
|
||||
const sec = Number(ss)
|
||||
return h >= 0 && h <= 23 && min >= 0 && min <= 59 && sec >= 0 && sec <= 59
|
||||
}
|
||||
|
||||
export function formatIsoDateTimeToDisplay(s: string | null): string {
|
||||
if (!s || !isValidIsoDateTime(s)) return ''
|
||||
const [date, time] = s.split('T')
|
||||
const [y, mo, d] = date.split('-')
|
||||
const [hh, mm] = time.split(':')
|
||||
return `${d}/${mo}/${y} ${hh}:${mm}`
|
||||
}
|
||||
|
||||
export function splitDateTime(s: string | null): {date: string | null; time: string} {
|
||||
if (!s || !isValidIsoDateTime(s)) return {date: null, time: ''}
|
||||
const [date, time] = s.split('T')
|
||||
return {date, time: time.slice(0, 5)}
|
||||
}
|
||||
|
||||
export function composeDateTime(date: string, time: string): string {
|
||||
const t = time || '00:00'
|
||||
return `${date}T${t}:00`
|
||||
}
|
||||
Reference in New Issue
Block a user