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

LettreSignificationExemple
y / yyyyAnnée26 / 2026
M / MM / MMM / MMMMMois4 / 04 / avr. / avril
d / ddJour du mois5 / 05
E / EEEEJour de la semainelun. / lundi
H / HHHeure (0–23)9 / 09
h / hhHeure (1–12)9 / 09
m / mmMinute5 / 05
s / ssSeconde4 / 04
aAM/PMAM
z / zzzzFuseau (abréviation/nom)CET / heure d'Europe centrale
X / XXXOffset 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 yyyy et YYYY : YYYY est l'année de la semaine ISO, pas l'année calendaire. Au 31 décembre, vous pouvez obtenir une année fausse. Utilisez toujours yyyy.
  • Confondre MM et mm : MM est le mois, mm est 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 LocalDateTime n'a pas de fuseau. Convertissez en ZonedDateTime avant 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.