Altro
Conversione da stringa a data in Java
Qual è il modo migliore per convertire una Stringa
nel formato '2 gennaio 2010' in una Data
in Java?
In definitiva, voglio scomporre il mese, il giorno e l'anno come numeri interi in modo da poter usare
Date date = new Date();
date.setMonth()..
date.setYear()..
date.setDay()..
date.setlong currentTime = date.getTime();
per convertire la data in tempo.
844
3
Questo è il modo più difficile, e quei metodi setter
java.util.Date
sono stati deprecati da Java 1.1 (1997). Formattate semplicemente la data usandoSimpleDateFormat
usando un pattern di formato corrispondente alla stringa di input.Nel tuo caso specifico di "2 gennaio 2010" come stringa di input:
"Gennaio" è il mese del testo completo, quindi usa il pattern
MMMM
per esso"2" è il giorno breve del mese, quindi usa il pattern
d
per esso."2010" è l'anno a 4 cifre, quindi usa il modello
yyyy
."!-->
Si noti l'importanza dell'argomento esplicito
Locale
. Se lo ometti, allora userà il locale di default che non è necessariamente l'inglese come usato nel nome del mese della stringa di input. Se il locale non corrisponde alla stringa di input, allora si otterrebbe confusamente unajava.text.ParseException
anche se il modello di formato sembra valido.Ecco un estratto di rilevanza da il javadoc, che elenca tutti i pattern di formato disponibili:
Si noti che i modelli sono sensibili alle maiuscole e che i modelli basati sul testo di quattro o più caratteri rappresentano la forma completa; altrimenti viene usata una forma breve o abbreviata se disponibile. Quindi, ad esempio,
MMMMM
o più non è necessario.Ecco alcuni esempi di modelli validi di
SimpleDateFormat
per analizzare una data stringa:Una nota importante è che
SimpleDateFormat
non è non thread safe. In altre parole, non si dovrebbe mai dichiararlo e assegnarlo come variabile statica o di istanza e poi riutilizzarlo da diversi metodi/thread. Dovreste sempre crearlo nuovo di zecca all'interno dell'ambito locale del metodo.Java 8 update
Se ti capita di essere su Java 8 o più recente, allora usa
DateTimeFormatter
(anche qui, clicca sul link per vedere tutti i formattatori predefiniti e i modelli di formato disponibili; il tutorial è disponibile qui). Questa nuova API è ispirata da JodaTime.Nota: se il tuo schema di formato contiene anche la parte dell'ora, allora usa
LocalDateTime#parse(text, formatter)
invece diLocalDate#parse(text, formatter)
. E, se il tuo modello di formato contiene anche il fuso orario, allora usaZonedDateTime#parse(text, formatter)
invece di [ZonedDateTime#parse(text, formatter)
].Ecco un estratto rilevante dal javadoc, che elenca tutti i pattern di formato disponibili:
Si noti che ha diversi formattatori predefiniti per i modelli più popolari. Quindi, invece di ad esempio
DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH);
, si potrebbe usareDateTimeFormatter.RFC_1123_DATE_TIME
. Questo è possibile perché sono, al contrario diSimpleDateFormat
, thread safe. Potresti quindi anche definirne uno tuo, se necessario.Per un particolare formato di stringa in ingresso, non è necessario utilizzare un esplicito
DateTimeFormatter
: una data standard ISO 8601, come 2016-09-26T17:44:57Z, può essere analizzata direttamente conLocalDateTime#parse(text)
poiché utilizza già il formattatoreISO_LOCAL_DATE_TIME
. Allo stesso modo,LocalDate#parse(text)
analizza una data ISO senza la componente temporale (vediISO_LOCAL_DATE
), eZonedDateTime#parse(text)
analizza una data ISO con un offset e un fuso orario aggiunto (vediISO_ZONED_DATE_TIME
).Ah sì, la discussione su Java Date, di nuovo. Per trattare la manipolazione delle date usiamo Date, Calendar, GregorianCalendar, e SimpleDateFormat. Per esempio usando la tua data di gennaio come input:
Poi si può manipolare con qualcosa come:
Mentre si tratta della classe SimpleDateFormat, è importante ricordare che Date non è thread-safe e non è possibile condividere un singolo oggetto Date con più thread.
Inoltre c'è una grande differenza tra "m" e "M" dove le minuscole sono usate per i minuti e le maiuscole per il mese. Lo stesso con "d" e "D". Questo può causare sottili bug che spesso vengono trascurati. Vedi Javadoc o Guida alla conversione di stringhe in date in Java per maggiori dettagli.