Problem z formatem daty z DateTimeFormatter [duplicate]
Mam datę w następującym formacie: 1/1/2020 3:4:7 AMPróbuję sformatować ją za pomocą DateTimeFormatter.
Mam następujący kod z programem formatującym do przeanalizowania go, ale to nie działa.
LocalDateTime date = LocalDateTime.parse("1/1/2020 3:4:7 AM", DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"));
Otrzymuję następujący wyjątek:
java.time.format.DateTimeParseException: Text '1/1/2020 3:4:7 AM' could not be parsed at index 0
Czy ktoś może mi pomóc?
Odpowiedzi
Dwa oddzielne problemy:
Źle się liczy
Używasz np. MMCo jest jawne: Zawsze pełna liczba cyfr, uzupełniona zerami. Twój ciąg nie jest taki, to tylko liczba. Więc zrób to M/d/uuuu h:m:s a.
EDYCJA: Zmieniono yyyyna uuuu, dzięki, @deHaar. Rozumowanie: yyyy lub uuuu rzadko mają znaczenie, ale pamiętaj, że to oznacza, że wymagane są 4 cyfry . Różnica pojawia się latami przed 0: uuuustaje się ujemna, yyyynie ma i oczekuje, że użyjesz np. Aby GGuzyskać 44 BCzamiast -44. W ten sposób uuuujest po prostu bardziej poprawny, chociaż zwykle różnica nie będzie się pojawiać.
Brak języka
Drugi problem polega na tym, że prawie nigdy nie powinieneś używać tej wersji ofPattern- ma błąd, którego nie można złapać za pomocą testów jednostkowych, co sprawia, że jest to błąd, który jest tysiące razy „cięższy”, a tym samym prawdziwy problem .
Musisz określić lokalizację. Bez tego 'AM' nie będzie analizować, chyba że domyślnym językiem platformy jest angielski.
Składając to razem
LocalDateTime date = LocalDateTime.parse("1/1/2020 3:4:7 AM",
DateTimeFormatter.ofPattern("M/d/uuuu h:m:s a", Locale.ENGLISH));
działa świetnie.
W Twoim fragmencie:
LocalDateTime
.parse("1/1/2020 3:4:7 AM", DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"));
1- nie pasujeMM1- nie pasujedd3- nie pasujehh4- nie pasujemm7- nie pasujess
tzn. długości części wzorca formatera (np. MM) i ich odpowiednich części z tekstu ciągu (np. 1) nie są zgodne.
Możesz je dopasować na kilka sposobów, np. Możesz albo zmienić tekst ciągu, aby pasował do wzorca formatera, albo odwrotnie.
Zamiast tego możesz spróbować:
LocalDateTime
.parse("01/01/2020 03:04:07 AM", DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"));
Ponadto spójrz na Wzory liter i symboli .
Użyj pojedynczych liter dla składników daty i godziny (miesiąc, dzień, rok, godzina, minuta i sekunda).
Możesz również sprawić, aby program formatujący obsługiwał wzorzec w sposób niewrażliwy na wielkość liter (np. Rano, przed południem, rano), jak pokazano poniżej:
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.util.Locale; public class Main { public static void main(String[] args) { // Formatter to handle the pattern in case insensitive way (e.g. am, AM, Am) DateTimeFormatter formatter = new DateTimeFormatterBuilder() .parseCaseInsensitive() .appendPattern("M/d/u h:m:s a") .toFormatter(Locale.ENGLISH); LocalDateTime date = LocalDateTime.parse("1/1/2020 3:4:7 AM", formatter); System.out.println(date); } }
Wynik:
2020-01-01T03:04:07
Zgodnie z dokumentacją DateTimeFormatter :
Liczba: jeśli liczba liter wynosi jeden , wartość jest wyprowadzana przy użyciu minimalnej liczby cyfr i bez dopełnienia. W przeciwnym razie liczba cyfr jest używana jako szerokość pola wyjściowego, przy czym w razie potrzeby wartość jest uzupełniana zerami.
Odwracając rozumowanie, możesz spróbować użyć tego programu formatującego:
DateTimeFormatter.ofPattern("M/d/yyyy h:m:s a")