To trudna droga, a te java.util.Date
metody ustawiające są przestarzałe od wersji Java 1.1 (1997). Po prostu sformatuj datę, używając SimpleDateFormat
wzorca formatu pasującego do ciągu wejściowego .
W konkretnym przypadku „2 stycznia 2010 r.” Jako ciąg wejściowy:
- „Styczeń” to miesiąc pełnego tekstu, więc użyj do tego
MMMM
wzorca
- „2” to krótki dzień miesiąca, więc użyj
d
wzoru.
- „2010” jest 4-cyfrowym rokiem, więc użyj
yyyy
wzoru.
String string = "January 2, 2010";
DateFormat format = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH);
Date date = format.parse(string);
System.out.println(date); // Sat Jan 02 00:00:00 GMT 2010
Zwróć uwagę na znaczenie wyraźnego Locale
argumentu. Jeśli go pominiesz, użyje domyślnych ustawień regionalnych, które niekoniecznie są angielskie, jak w nazwie miesiąca łańcucha wejściowego. Jeśli ustawienia narodowe nie pasują do ciągu wejściowego, to myląco można uzyskać, java.text.ParseException
nawet jeśli wzorzec formatu wydaje się prawidłowy.
Oto wyciąg z javadoc , zawierający wszystkie dostępne wzorce formatów:
Letter Date or Time Component Presentation Examples
------ ---------------------- ------------------ -------------------------------------
G Era designator Text AD
y Year Year 1996; 96
Y Week year Year 2009; 09
M/L Month in year Month July; Jul; 07
w Week in year Number 27
W Week in month Number 2
D Day in year Number 189
d Day in month Number 10
F Day of week in month Number 2
E Day in week Text Tuesday; Tue
u Day number of week Number 1
a Am/pm marker Text PM
H Hour in day (0-23) Number 0
k Hour in day (1-24) Number 24
K Hour in am/pm (0-11) Number 0
h Hour in am/pm (1-12) Number 12
m Minute in hour Number 30
s Second in minute Number 55
S Millisecond Number 978
z Time zone General time zone Pacific Standard Time; PST; GMT-08:00
Z Time zone RFC 822 time zone -0800
X Time zone ISO 8601 time zone -08; -0800; -08:00
Zauważ, że we wzorach rozróżniana jest wielkość liter, a wzorce tekstowe składające się z czterech lub więcej znaków reprezentują pełną formę; w przeciwnym razie stosuje się krótką lub skróconą formę, jeśli jest dostępna. Więc np. MMMMM
Więcej nie jest konieczne.
Oto kilka przykładów prawidłowych SimpleDateFormat
wzorców do parsowania danego ciągu do tej pory:
Input string Pattern
------------------------------------ ----------------------------
2001.07.04 AD at 12:08:56 PDT yyyy.MM.dd G 'at' HH:mm:ss z
Wed, Jul 4, '01 EEE, MMM d, ''yy
12:08 PM h:mm a
12 o'clock PM, Pacific Daylight Time hh 'o''clock' a, zzzz
0:08 PM, PDT K:mm a, z
02001.July.04 AD 12:08 PM yyyyy.MMMM.dd GGG hh:mm aaa
Wed, 4 Jul 2001 12:08:56 -0700 EEE, d MMM yyyy HH:mm:ss Z
010704120856-0700 yyMMddHHmmssZ
2001-07-04T12:08:56.235-0700 yyyy-MM-dd'T'HH:mm:ss.SSSZ
2001-07-04T12:08:56.235-07:00 yyyy-MM-dd'T'HH:mm:ss.SSSXXX
2001-W27-3 YYYY-'W'ww-u
Ważną uwagą jest to, że nieSimpleDateFormat
jest bezpieczny dla wątków. Innymi słowy, nigdy nie powinieneś deklarować i przypisywać go jako zmiennej statycznej lub zmiennej instancji, a następnie ponownie użyć go z różnych metod / wątków. Zawsze powinieneś stworzyć go zupełnie nowy w ramach metody lokalnej.
Aktualizacja Java 8
Jeśli akurat korzystasz z Javy 8 lub nowszej, użyj DateTimeFormatter
(także tutaj, kliknij link, aby zobaczyć wszystkie predefiniowane formaterery i dostępne wzorce formatów; samouczek jest dostępny tutaj ). Ten nowy interfejs API jest inspirowany przez JodaTime .
String string = "January 2, 2010";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM d, yyyy", Locale.ENGLISH);
LocalDate date = LocalDate.parse(string, formatter);
System.out.println(date); // 2010-01-02
Uwaga: jeśli wzorzec formatu zawiera również część czasu, użyj LocalDateTime#parse(text, formatter)
zamiast niej LocalDate#parse(text, formatter)
. A jeśli twój wzór formatu zawiera również strefę czasową, użyj ZonedDateTime#parse(text, formatter)
zamiast tego.
Oto wyciąg z javadoc , zawierający wszystkie dostępne wzorce formatów:
Symbol Meaning Presentation Examples
------ -------------------------- ------------ ----------------------------------------------
G era text AD; Anno Domini; A
u year year 2004; 04
y year-of-era year 2004; 04
D day-of-year number 189
M/L month-of-year number/text 7; 07; Jul; July; J
d day-of-month number 10
Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter
Y week-based-year year 1996; 96
w week-of-week-based-year number 27
W week-of-month number 4
E day-of-week text Tue; Tuesday; T
e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T
F week-of-month number 3
a am-pm-of-day text PM
h clock-hour-of-am-pm (1-12) number 12
K hour-of-am-pm (0-11) number 0
k clock-hour-of-am-pm (1-24) number 0
H hour-of-day (0-23) number 0
m minute-of-hour number 30
s second-of-minute number 55
S fraction-of-second fraction 978
A milli-of-day number 1234
n nano-of-second number 987654321
N nano-of-day number 1234000000
V time-zone ID zone-id America/Los_Angeles; Z; -08:30
z time-zone name zone-name Pacific Standard Time; PST
O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00;
X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15;
x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15;
Z zone-offset offset-Z +0000; -0800; -08:00;
Pamiętaj, że ma kilka predefiniowanych formatów dla bardziej popularnych wzorów. Więc zamiast np. DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH);
Możesz użyć DateTimeFormatter.RFC_1123_DATE_TIME
. Jest to możliwe, ponieważ w przeciwieństwie do nich są SimpleDateFormat
bezpieczne dla nici. W razie potrzeby możesz także zdefiniować własne.
W przypadku określonego formatu ciągu wejściowego nie trzeba używać wyraźnego DateTimeFormatter
: standardową datę ISO 8601 , taką jak 2016-09-26T17: 44: 57Z, można bezpośrednio przeanalizować, LocalDateTime#parse(text)
ponieważ już używa ISO_LOCAL_DATE_TIME
formatyzatora. Podobnie, LocalDate#parse(text)
analizuje datę ISO bez komponentu czasu (patrz ISO_LOCAL_DATE
) i ZonedDateTime#parse(text)
analizuje datę ISO z dodanym przesunięciem i strefą czasową (patrz ISO_ZONED_DATE_TIME
).