diff --git a/frontend/src/components/DateField.jsx b/frontend/src/components/DateField.jsx
index 654b8b4..5899517 100644
--- a/frontend/src/components/DateField.jsx
+++ b/frontend/src/components/DateField.jsx
@@ -36,7 +36,7 @@ export default function DateField({ id, value, onChange, placeholder, className
else setText(dateToInputText(parsed))
}}
/>
- {touched && invalid && {t('Une année (1950) ou une date (12/03/1950)')}}
+ {touched && invalid && {t('Une année (1950) ou une date ({exemple})', { exemple: dateToInputText('1950-03-12') })}}
)
}
diff --git a/frontend/src/i18n/en/fiche.js b/frontend/src/i18n/en/fiche.js
index 6875eca..763869e 100644
--- a/frontend/src/i18n/en/fiche.js
+++ b/frontend/src/i18n/en/fiche.js
@@ -468,7 +468,7 @@ export default {
'Merci, c’est envoyé. Le moment apparaîtra dans sa vie quand la personne qui gère l’arbre l’aura accepté.': 'Thanks, it has been sent. The moment will show in their life once the person who manages the tree has accepted it.',
// Dates : année seule, décès sans date (issue #77)
'Année ou date': 'Year or date',
- 'Une année (1950) ou une date (12/03/1950)': 'A year (1950) or a date (12/03/1950)',
+ 'Une année (1950) ou une date ({exemple})': 'A year (1950) or a date ({exemple})',
'Date inconnue': 'Date unknown',
'date inconnue': 'date unknown',
'Décédé(e), date inconnue': 'Deceased, date unknown',
diff --git a/frontend/src/i18n/index.js b/frontend/src/i18n/index.js
index 7ee5100..63c50d3 100644
--- a/frontend/src/i18n/index.js
+++ b/frontend/src/i18n/index.js
@@ -32,8 +32,23 @@ function detectLocale() {
export const locale = typeof window === 'undefined' ? 'fr' : detectLocale()
-// Pour toLocaleDateString et consorts.
-export const dateLocale = locale === 'fr' ? 'fr-FR' : 'en-GB'
+// Pour toLocaleDateString et consorts. En anglais, la région du navigateur décide de l'ordre jour/mois
+// (en-US : 10/25/2026) ; hors anglais (interface anglaise sur un navigateur allemand…), en-GB (issue #152).
+function englishDateLocale() {
+ const languages = typeof navigator === 'undefined' ? [] : (navigator.languages?.length ? navigator.languages : [navigator.language])
+ const english = languages.find((lang) => /^en-[a-z]{2}$/i.test(String(lang)))
+ if (!english) return 'en-GB'
+ try { return Intl.DateTimeFormat.supportedLocalesOf(english)[0] || 'en-GB' } catch { return 'en-GB' }
+}
+export const dateLocale = locale === 'fr' ? 'fr-FR' : englishDateLocale()
+
+// Le mois avant le jour dans les dates en chiffres de cette langue (en-US)
+export const monthFirst = (() => {
+ try {
+ const parts = new Intl.DateTimeFormat(dateLocale, { day: '2-digit', month: '2-digit', year: 'numeric' }).formatToParts(new Date(Date.UTC(2026, 9, 25)))
+ return parts.findIndex((p) => p.type === 'month') < parts.findIndex((p) => p.type === 'day')
+ } catch { return false }
+})()
if (typeof document !== 'undefined') document.documentElement.lang = locale
diff --git a/frontend/src/utils/dateInput.js b/frontend/src/utils/dateInput.js
index a47bb22..f202f27 100644
--- a/frontend/src/utils/dateInput.js
+++ b/frontend/src/utils/dateInput.js
@@ -1,14 +1,17 @@
// Saisie d'une date dans la fiche : une année seule (« 1950 ») ou une date complète (« 12/03/1950 »).
// L'année seule se range au 1er janvier, la convention de toute l'appli (issue #77).
+// L'ordre jour/mois suit la langue : « 03/12/1950 » pour un navigateur en-US (issue #152).
+import { monthFirst } from '../i18n/index.js'
const pad = (n) => String(n).padStart(2, '0')
// Valeur stockée (« 1950-01-01 », « 1950 », « 1950-03-12 ») vers le texte du champ
-export function dateToInputText(value) {
+export function dateToInputText(value, mdy = monthFirst) {
const raw = String(value ?? '').trim()
if (!raw) return ''
const full = raw.match(/^(\d{4})-(\d{2})-(\d{2})/)
- if (full) return full[2] === '01' && full[3] === '01' ? full[1] : `${full[3]}/${full[2]}/${full[1]}`
+ if (full) if (full[2] === '01' && full[3] === '01') return full[1]
+ return mdy ? `${full[2]}/${full[3]}/${full[1]}` : `${full[3]}/${full[2]}/${full[1]}`
const year = raw.match(/^(\d{4})$/)
return year ? year[1] : raw
}
@@ -21,7 +24,7 @@ export function formatDigitsAsDate(text) {
}
// Texte du champ vers la valeur stockée : '' si vide, « AAAA-MM-JJ » si valable, undefined si on ne comprend pas
-export function parseDateInput(text) {
+export function parseDateInput(text, mdy = monthFirst) {
const raw = String(text ?? '').trim()
if (!raw) return ''
if (/^\d{4}$/.test(raw)) return `${raw}-01-01`
@@ -30,7 +33,8 @@ export function parseDateInput(text) {
let year
const dmy = raw.match(/^(\d{1,2})[/.\-\s](\d{1,2})[/.\-\s](\d{4})$/)
const iso = raw.match(/^(\d{4})-(\d{2})-(\d{2})$/)
- if (dmy) [, day, month, year] = dmy
+ if (dmy && mdy) [, month, day, year] = dmy
+ else if (dmy) [, day, month, year] = dmy
else if (iso) [, year, month, day] = iso
else return undefined
const d = Number(day)
diff --git a/frontend/src/utils/dateInput.test.js b/frontend/src/utils/dateInput.test.js
index 5b0b668..6e0db7f 100644
--- a/frontend/src/utils/dateInput.test.js
+++ b/frontend/src/utils/dateInput.test.js
@@ -38,3 +38,16 @@ describe('formatDigitsAsDate', () => {
expect(formatDigitsAsDate('1/3/1950')).toBe('1/3/1950')
})
})
+
+describe('ordre mois/jour d un navigateur en-US (issue #152)', () => {
+ it('affiche et lit le mois avant le jour', () => {
+ expect(dateToInputText('1950-03-12', true)).toBe('03/12/1950')
+ expect(parseDateInput('03/12/1950', true)).toBe('1950-03-12')
+ expect(parseDateInput('12/25/1950', true)).toBe('1950-12-25')
+ expect(parseDateInput('25/12/1950', true)).toBeUndefined()
+ })
+ it('une année seule ne change pas', () => {
+ expect(dateToInputText('1950-01-01', true)).toBe('1950')
+ expect(parseDateInput('1950', true)).toBe('1950-01-01')
+ })
+})