Afficher une java.util.Date dans un format spécifique
Afficher une date dans un format précis (jj/mm/aaaa, yyyy-MM-dd HH:mm, EEEE d MMMM yyyy…) est l'une des opérations les plus fréquentes en Java. Deux API se partagent le terrain : l'ancienne SimpleDateFormat et la moderne DateTimeFormatter (Java 8+).
L'approche moderne : DateTimeFormatter (Java 8+)
Privilégiez toujours cette API sur un projet récent — elle est thread-safe, immuable et plus lisible.
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
LocalDateTime maintenant = LocalDateTime.now();
DateTimeFormatter fr = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm", Locale.FRANCE);
System.out.println(maintenant.format(fr));
// 20/04/2026 14:35
DateTimeFormatter complet = DateTimeFormatter.ofPattern("EEEE d MMMM yyyy", Locale.FRANCE);
System.out.println(maintenant.format(complet));
// lundi 20 avril 2026
Les patterns les plus utiles
| Lettre | Signification | Exemple |
|---|---|---|
y / yyyy | Année | 26 / 2026 |
M / MM / MMM / MMMM | Mois | 4 / 04 / avr. / avril |
d / dd | Jour du mois | 5 / 05 |
E / EEEE | Jour de la semaine | lun. / lundi |
H / HH | Heure (0–23) | 9 / 09 |
h / hh | Heure (1–12) | 9 / 09 |
m / mm | Minute | 5 / 05 |
s / ss | Seconde | 4 / 04 |
a | AM/PM | AM |
z / zzzz | Fuseau (abréviation/nom) | CET / heure d'Europe centrale |
X / XXX | Offset UTC | +01 / +01:00 |
Exemples de formats complets
DateTimeFormatter f1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// 2026-04-20
DateTimeFormatter f2 = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
// 20/04/2026 14:35:12
DateTimeFormatter f3 = DateTimeFormatter.ofPattern("EEEE d MMMM yyyy 'à' HH'h'mm", Locale.FRANCE);
// lundi 20 avril 2026 à 14h35
DateTimeFormatter f4 = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
// 2026-04-20T14:35:12.482
Les caractères littéraux doivent être entourés de simples quotes ('à', 'h') pour ne pas être interprétés comme des symboles de pattern.
Gérer les fuseaux horaires
Pour formater une instant avec un fuseau précis, utilisez ZonedDateTime :
import java.time.*;
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Europe/Paris"));
DateTimeFormatter f = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm zzzz", Locale.FRANCE);
System.out.println(zdt.format(f));
// 20/04/2026 14:35 heure d'Europe centrale
L'ancienne API : SimpleDateFormat
Sur du legacy (Java 7 et avant, ou code historique), vous rencontrerez SimpleDateFormat :
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm", Locale.FRANCE);
String formatted = sdf.format(new Date());
// 20/04/2026 14:35
⚠ SimpleDateFormat n'est pas thread-safe. Ne le partagez jamais comme champ statique sans synchronisation. Si vous devez rester sur cette API, créez une nouvelle instance à chaque appel, ou utilisez un ThreadLocal<SimpleDateFormat>.
Convertir une Date (legacy) en LocalDateTime
Pour passer d'une vieille java.util.Date à l'API moderne :
Date vieille = new Date();
LocalDateTime moderne = vieille.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime();
Parser une chaîne vers une date
Le mécanisme inverse utilise la même DateTimeFormatter :
DateTimeFormatter f = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate d = LocalDate.parse("20/04/2026", f);
Pièges courants
- Confondre
yyyyetYYYY:YYYYest l'année de la semaine ISO, pas l'année calendaire. Au 31 décembre, vous pouvez obtenir une année fausse. Utilisez toujoursyyyy. - Confondre
MMetmm:MMest le mois,mmest la minute. - Oublier la locale : sans
Locale.FRANCE, le nom du jour ou du mois peut sortir en anglais selon la JVM. - Ignorer le fuseau : une
LocalDateTimen'a pas de fuseau. Convertissez enZonedDateTimeavant d'afficher ou de stocker.
Recommandation
Sur tout nouveau code : java.time (LocalDate, LocalDateTime, ZonedDateTime) et DateTimeFormatter. L'API est cohérente, immuable, thread-safe et complète. Laissez SimpleDateFormat à la maintenance de vieux projets.