Więcej
Konwersja łańcucha Java na datę
Jaki jest najlepszy sposób konwersji String
w formacie 'January 2, 2010' na Date
w Javie?
Ostatecznie chcę wyodrębnić miesiąc, dzień i rok jako liczby całkowite, aby móc użyć
Date date = new Date();
date.setMonth()..
date.setYear()..
date.setDay()..
date.setlong currentTime = date.getTime();
do konwersji daty na czas.
844
3
To jest trudny sposób, a te metody setera
java.util.Date
są przestarzałe od Java 1.1 (1997). Po prostu sformatuj datę za pomocąSimpleDateFormat
używając wzorca formatu pasującego do łańcucha wejściowego.W twoim konkretnym przypadku "2 stycznia 2010" jako ciąg wejściowy:
MMMM
.d
.yyy
.Zwróć uwagę na znaczenie jawnego argumentu
Locale
. Jeśli go pominiesz, to zostanie użyte domyślne locale, które niekoniecznie jest angielskie, jak użyte w nazwie miesiąca łańcucha wejściowego. Jeśli locale nie'pasuje do łańcucha wejściowego, wtedy myląco otrzymasz wyjątekjava.text.ParseException
, nawet jeśli wzorzec formatu wydaje się poprawny.Oto'fragment odnośnika z javadoc, wymieniający wszystkie dostępne wzorce formatu:
Zauważ, że we wzorcach rozróżniana jest wielkość liter i że wzorce tekstowe składające się z czterech lub więcej znaków reprezentują pełną formę; w przeciwnym razie używana jest forma skrócona lub skrócona, jeśli jest dostępna. Tak więc np.
MMMMM
lub więcej nie jest konieczne.Oto kilka przykładów poprawnych wzorców
SimpleDateFormat
do przetworzenia danego łańcucha na datę:Ważną informacją jest to, że
SimpleDateFormat
nie jest bezpieczny dla wątków. Innymi słowy, nigdy nie powinieneś deklarować i przypisywać go jako zmiennej statycznej lub instancji, a następnie używać go ponownie w różnych metodach/wątkach. Powinieneś zawsze tworzyć ją od nowa w lokalnym zakresie metody.Java 8 aktualizacja
Jeśli masz Javę 8 lub nowszą, użyj
DateTimeFormatter
(także tutaj, kliknij link, aby zobaczyć wszystkie predefiniowane formatery i dostępne wzorce formatów; samouczek jest dostępny tutaj). To nowe API jest inspirowane przez JodaTime.Uwaga: jeśli twój wzorzec formatu zawiera również część czasową, użyj
LocalDateTime#parse(text, formatter)
zamiastLocalDate#parse(text, formatter)
. A jeśli twój wzorzec formatu zawiera również strefę czasową, wtedy użyjZonedDateTime#parse(text, formatter)
zamiast [ZonedDateTime#parse(text, formatter)
].Poniżej'znajduje się fragment istotny z javadoc, wymieniający wszystkie dostępne wzorce formatu:
Zwróć uwagę, że ma on kilka predefiniowanych formaterów dla bardziej popularnych wzorców. Więc zamiast np.
DateTimeFormatter.ofPattern("EEE, d MMM yyy HH:mm:ss Z", Locale.ENGLISH);
, możesz użyćDateTimeFormatter.RFC_1123_DATE_TIME
. Jest to możliwe, ponieważ są one, w przeciwieństwie doSimpleDateFormat
, bezpieczne dla wątków. Możesz więc również zdefiniować swoje własne, jeśli to konieczne.Dla konkretnego formatu łańcucha wejściowego, nie trzeba używać jawnego
DateTimeFormatter
: standardowa ISO 8601 data, jak 2016-09-26T17:44:57Z, może być bezpośrednio parsowana za pomocąLocalDateTime#parse(text)
, ponieważ już używa formateraISO_LOCAL_DATE_TIME
. Podobnie,LocalDate#parse(text)
parsuje datę ISO bez składnika czasu (zobaczISO_LOCAL_DATE
), aZonedDateTime#parse(text)
parsuje datę ISO z przesunięciem i dodaną strefą czasową (zobaczISO_ZONED_DATE_TIME
).Ach tak, znowu dyskusja o datach w Javie. Aby poradzić sobie z manipulacją datą używamy Date, Calendar, GregorianCalendar i SimpleDateFormat. Na przykład używając twojej styczniowej daty jako danych wejściowych:
Następnie możesz manipulować tym za pomocą czegoś takiego jak:
Podczas pracy z klasą SimpleDateFormat należy pamiętać, że Date nie jest bezpieczna dla wątków i nie można współdzielić pojedynczego obiektu Date z wieloma wątkami.
Istnieje również duża różnica pomiędzy "m" i "M", gdzie mała litera jest używana dla minut, a duża dla miesiąca. Tak samo jest z "d" i "D". Może to powodować subtelne błędy, które często są przeoczone. Zobacz Javadoc lub Guide to Convert String to Date in Java po więcej szczegółów.