1. DateTimeFormatter: che cos’è e a cosa serve
Nelle applicazioni reali le date raramente vivono solo all’interno del codice. Di solito bisogna:
- Convertirle in stringa per stampare in console, a schermo o su file (per esempio, "01.06.2025 14:30").
- Eseguire il parsing di una stringa, cioè trasformare una stringa inserita dall’utente o proveniente da un file di nuovo in un oggetto data/ora.
Per questo, in Java c’è uno strumento potente e comodo — la classe java.time.format.DateTimeFormatter.
Si può dire che DateTimeFormatter sia un traduttore tra oggetti temporali (LocalDate, LocalDateTime, ZonedDateTime, Instant e altri) e stringhe. Sa:
- Trasformare oggetti data/ora in stringhe nel formato desiderato (format — formattazione).
- Trasformare stringhe in oggetti data/ora (parse — parsing).
2. Formatter standard: rapido e semplice
Java ha preparato per noi un set di formatter standard che coprono i formati ISO più popolari (standard internazionali per date e orari).
Ecco alcuni di essi:
| Formatter | Esempio di stringa | Descrizione |
|---|---|---|
|
2025-06-01 | Solo data (anno-mese-giorno) |
|
14:30:00 | Solo orario (ore:minuti:secondi) |
|
2025-06-01T14:30:00 | Data e ora senza fuso orario |
|
2025-06-01T14:30:00+03:00[Europe/Minsk] | Data, ora e fuso orario |
Esempio d’uso di un formatter standard
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class FormatterDemo {
public static void main(String[] args) {
LocalDate date = LocalDate.now();
// Formattiamo la data in una stringa
String text = date.format(DateTimeFormatter.ISO_LOCAL_DATE);
System.out.println(text); // Ad esempio, 2025-06-01
// Eseguiamo il parsing della stringa di nuovo in una data
LocalDate parsed = LocalDate.parse("2025-06-01", DateTimeFormatter.ISO_LOCAL_DATE);
System.out.println(parsed); // 2025-06-01
}
}
Analogia
Se Java fosse una caffetteria, i formatter standard sarebbero «americano», «latte» ed «espresso». Veloce, standard, ma a volte si desidera qualcosa di speciale!
3. Modelli personalizzati: DateTimeFormatter.ofPattern
A volte i formati standard non bastano. Per esempio, bisogna stampare la data come "01.06.2025 14:30" e non come "2025-06-01T14:30:00". Per questo possiamo creare un nostro modello con il metodo DateTimeFormatter.ofPattern(String pattern).
Sintassi dei modelli
Nel modello si usano lettere speciali:
- y — anno (yyyy — 2025)
- M — mese (MM — 06)
- d — giorno (dd — 01)
- H — ora (formato 24 ore, HH — 14)
- m — minuti (mm — 30)
- s — secondi (ss — 00)
Esempi di modelli
| Modello | Esempio di risultato |
|---|---|
|
01.06.2025 |
|
2025/06/01 |
|
01.06.2025 14:30 |
|
2025-06-01 14:30:00 |
|
1 iyunya 2025 (con locale russo) |
Esempio: formattazione di data e ora
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class CustomFormatDemo {
public static void main(String[] args) {
LocalDateTime dt = LocalDateTime.of(2025, 6, 1, 14, 30);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
String text = dt.format(formatter);
System.out.println(text); // 01.06.2025 14:30
}
}
Esempio: parsing di una stringa in data
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class ParseDemo {
public static void main(String[] args) {
String input = "01.06.2025 14:30";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
LocalDateTime dt = LocalDateTime.parse(input, formatter);
System.out.println(dt); // 2025-06-01T14:30
}
}
Attenzione: il modello deve corrispondere esattamente alla stringa! Se nella stringa ci sono i secondi — aggiungete :ss al modello.
4. Formattazione: convertiamo data/ora in stringa
Schema generale
- Creiamo l’oggetto necessario (LocalDate, LocalDateTime, ZonedDateTime ecc.).
- Creiamo o scegliamo il formatter necessario.
- Chiamiamo sul nostro oggetto il metodo format(DateTimeFormatter) e otteniamo la stringa.
Esempio: stampiamo la data in diversi formati
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class MultiFormatDemo {
public static void main(String[] args) {
LocalDate date = LocalDate.of(2025, 6, 1);
// ISO standard
System.out.println(date.format(DateTimeFormatter.ISO_LOCAL_DATE)); // 2025-06-01
// Formato personalizzato
DateTimeFormatter rusFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy");
System.out.println(date.format(rusFormat)); // 01.06.2025
// Stile inglese
DateTimeFormatter usFormat = DateTimeFormatter.ofPattern("MM/dd/yyyy");
System.out.println(date.format(usFormat)); // 06/01/2025
}
}
Formattazione dell’orario
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class TimeFormatDemo {
public static void main(String[] args) {
LocalTime time = LocalTime.of(14, 30, 5);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
System.out.println(time.format(formatter)); // 14:30:05
}
}
5. Parsing: trasformiamo una stringa in data/ora
Schema generale
- Riceviamo una stringa (per esempio, dall’utente).
- Creiamo un formatter con lo stesso modello della stringa.
- Chiamiamo il metodo statico parse() o il metodo parse() dell’oggetto formatter.
Esempio: parsing di una data
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class ParseDateDemo {
public static void main(String[] args) {
String input = "01.06.2025";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
LocalDate date = LocalDate.parse(input, formatter);
System.out.println(date); // 2025-06-01
}
}
Esempio: parsing di data e ora
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class ParseDateTimeDemo {
public static void main(String[] args) {
String input = "01.06.2025 14:30";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
LocalDateTime dateTime = LocalDateTime.parse(input, formatter);
System.out.println(dateTime); // 2025-06-01T14:30
}
}
6. Gestione degli errori di parsing
Il parsing può essere insidioso. Se la stringa non corrisponde al modello, Java lancerà l’eccezione DateTimeParseException. È una situazione normale, ad esempio quando l’utente inserisce una data errata.
Esempio: gestione degli errori durante il parsing
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
public class ParseErrorDemo {
public static void main(String[] args) {
String input = "32.13.2025"; // Data non valida
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
try {
LocalDate date = LocalDate.parse(input, formatter);
System.out.println(date);
} catch (DateTimeParseException ex) {
System.out.println("Errore di parsing: " + ex.getMessage());
}
}
}
Importante: gestite sempre questi errori quando lavorate con input dell’utente!
7. Pratica: conversione delle date per l’utente
Supponiamo che nella nostra app didattica ci sia un compito: l’utente inserisce la data di nascita nel formato "dd.MM.yyyy" e il programma deve stampare la data nel formato "yyyy/MM/dd", oltre al giorno della settimana.
Esempio
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Scanner;
public class BirthdayFormatDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Inserisci la data di nascita (dd.MM.yyyy): ");
String input = scanner.nextLine();
DateTimeFormatter inputFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy");
DateTimeFormatter outputFormat = DateTimeFormatter.ofPattern("yyyy/MM/dd");
try {
LocalDate birthday = LocalDate.parse(input, inputFormat);
String formatted = birthday.format(outputFormat);
System.out.println("La tua data nel nuovo formato: " + formatted);
System.out.println("Giorno della settimana: " + birthday.getDayOfWeek()); // Ad esempio, SATURDAY
} catch (DateTimeParseException ex) {
System.out.println("Errore: formato della data non valido!");
}
}
}
8. Localizzazione: come la lingua influisce sulla formattazione
Con DateTimeFormatter si può non solo cambiare l’ordine dei numeri, ma anche stampare il mese in lettere, il giorno della settimana, ecc. Tenendo conto della locale (lingua e regione).
Esempio: mese in lettere in russo
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class LocaleDemo {
public static void main(String[] args) {
LocalDate date = LocalDate.of(2025, 6, 1);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d MMMM yyyy", new Locale("ru"));
System.out.println(date.format(formatter)); // 1 iyunya 2025
}
}
Esempio: locale inglese
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class LocaleEnDemo {
public static void main(String[] args) {
LocalDate date = LocalDate.of(2025, 6, 1);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d MMMM yyyy", Locale.ENGLISH);
System.out.println(date.format(formatter)); // 1 June 2025
}
}
Suggerimento: se volete che mese e giorno della settimana siano nella lingua desiderata — indicate esplicitamente la locale!
9. Errori tipici nella formattazione e nel parsing delle date
Errore n. 1: modello e stringa non corrispondono.
Se la stringa è "01.06.2025 14:30" ma il modello è "dd.MM.yyyy", il parsing fallirà. Il modello deve corrispondere esattamente alla stringa.
Errore n. 2: simboli del modello confusi.
MM — mese, mm — minuti. Se scrivete "dd.mm.yyyy", Java penserà che intendete i minuti e genererà un errore. Per il mese usate sempre la M maiuscola.
Errore n. 3: eccezioni di parsing non gestite.
Se non intercettate DateTimeParseException, il programma potrebbe terminare inaspettatamente in caso di input non corretto dell’utente. Gestite sempre questi errori.
Errore n. 4: locale non specificata quando si usano parole.
Se usate un modello con il mese in lettere (MMMM) e non indicate la locale, Java potrebbe usare la lingua predefinita (ad esempio, l’inglese). Impostate sempre esplicitamente la locale necessaria.
Errore n. 5: uso di classi vecchie (SimpleDateFormat, Date) nei nuovi progetti.
Ricordate: nel codice moderno usate solo java.time e DateTimeFormatter.
GO TO FULL VERSION