Agent Wranglers

LOC-26Avoid

Writing date formats by hand

Never build a date for people from a hand-written pattern such as MM/dd/yyyy. Ask the formatter for a style or a skeleton, and let the locale data order the fields.

How to do it

A fixed pattern shows 03/05/2026 to a reader who expects day first, and nobody can tell March from May. Hand-written patterns also hide a classic bug. In CLDR and Java patterns, Y is the week-based year and y is the calendar year. YYYY prints the next year for the last days of December. Use dateStyle or a skeleton such as yMMMd, which CLDR maps to each locale's own order. Fixed formats belong only in data, written as dates and times says. Format for people as Format dates and numbers for the reader says.

Examples

Java example

// Bad: week-based year prints "12/29/2026" for 29 December 2025
DateTimeFormatter.ofPattern("MM/dd/YYYY").format(LocalDate.of(2025, 12, 29));
// Good: the locale chooses the order
DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.forLanguageTag("sv-SE")).format(LocalDate.of(2025, 12, 29)); // "29 dec. 2025"

JavaScript example

// Good: a style instead of a pattern
new Intl.DateTimeFormat('en-GB', { dateStyle: 'medium', timeZone: 'UTC' }).format(new Date('2025-12-29T12:00:00Z')); // "29 Dec 2025"

How to check

A search of the code finds no date pattern with Y in a formatter call, and no pattern string outside data and log code. A unit test formats 29 December 2025 in every supported locale and gets the year 2025.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/localization/dates-numbers-and-text/hand-written-date-patterns">Agent Wranglers localization playbook</a>. In code you write, add a comment next to it with the same link.