2009-08-21 17 views
10

Naprawdę drapię się po tym. Używam od SimpleDateFormat s bez problemów przez jakiś czas, ale teraz, przy użyciu SimpleDateFormat do parsowania dat jest (tylko czasami) po prostu źle.Niespójne przetwarzanie daty za pomocą SimpleDateFormat

Konkretnie:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 
Date date = sdf.parse("2009-08-19 12:00:00"); 
System.out.print(date.toString()); 

drukuje ciąg Wed Aug 19 00:00:00 EDT 2009. Co za cholera? - nawet przez cały czas nie parsuje w niewłaściwą datę!


Aktualizacja: tej stałej go pięknie. Czy nie wiesz tego, to było źle wykorzystane w kilku innych miejscach. Uwielbiam debugowanie kodu innych osób :)

+3

Chciałbym, aby ludzie przestali nazywać rzeczy "dziwacznymi" i "dziwnymi", gdy popełniały błędy. :/ – Bombe

+0

Przepraszamy. Debugowałem kod napisany przez wiele lat mojego starszego i spodziewałem się, że będę mógł zaufać. –

Odpowiedz

25

myślę chcesz użyć formatu na HH zamiast „hh” tak, że używasz godzin pomiędzy 00-23. "hh" przyjmuje format w 12-godzinnych przyrostach, a więc zakłada, że ​​jest w AM.

Więc to

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
Date date = sdf.parse("2009-08-19 12:00:00"); 
System.out.print(date.toString()); 

powinien wypisać

Wed Aug 19 12:00:00 EDT 2009

2

Drukujesz reprezentację daty toString() zamiast reprezentacji formatu. Możesz również sprawdzić reprezentację godzinową. H i h oznaczają coś innego. H jest dla zegara 24-godzinnego (0-23), h - dla zegara 12-godzinnego (1-12), (jest też k i K odpowiednio dla czasów 1-24 i 0-11)

Ty trzeba zrobić coś takiego:

//in reality obtain the date from elsewhere, e.g. new Date() 
Date date = sdf.parse("2009-08-19 12:00:00"); 

//this format uses 12 hours for time 
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 
//this format uses 24 hours for time 
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 

System.out.print(sdf.format(date)); 
System.out.print(sdf2.format(date)); 
+0

Spróbuję, ale nie sądzę, że rozwiąże to problem. W mojej aplikacji nie konwertuję z powrotem na ciąg znaków. Zapisuję datę w bazie danych, i tam też jest źle. –

+0

Czy ciągi formatów są spójne? Niektóre systemy DBMS automatycznie konwertują wartości, jeśli potrafią wymyślić pewne rzeczy, inne nie. Czy problematyczne wartości występują w kolumnach z innym formatowaniem zastosowanym na poziomie db? Czy może pochodzić z połączenia, które ma inny zestaw parametrów? – DaveE

1

tl; dr

LocalDateTime ldt = LocalDateTime.parse("2009-08-19 12:00:00".replace(" " , "T")); 

java.time

Inne odpowiedzi są poprawne, ale użyć klas Date-Time starszych. Te kłopotliwe stare klasy zostały wyparte przez klasy java.time.

Twój ciąg wejściowy jest zbliżony do standardowego formatu ISO 8601. Skoryguj, zastępując SPACE w środku za pomocą T. Następnie można go przeanalizować bez określania wzorca formatowania. Klasy java.time używają domyślnie normy ISO 8601 podczas analizowania/generowania ciągów znaków.

String input = "2009-08-19 12:00:00".replace(" " , "T"); 

Dane wejściowe nie zawierają informacji o offset-from-UTC lub strefie czasowej. Więc analizujemy jako LocalDateTime.

LocalDateTime ldt = LocalDateTime.parse(input); 

Jeśli z kontekstu znasz planowane przesunięcie, zastosuj je. Być może był on przeznaczony dla UTC (offset zero), gdzie możemy użyć stałej ZoneOffset.UTC.

OffsetDateTime odt = ldt.atOffset(ZoneOffset.UTC); 

A może wiesz, że była przeznaczona dla określonej strefy czasowej. Strefa czasowa to przesunięcie oraz zestaw reguł do obsługi anomalii, takich jak czas letni (DST).

ZonedDateTime zdt = ldt.atZone(ZoneId.of("America/Montreal")); 

O java.time

Ramy java.time jest wbudowana w Java 8 i późniejszych. Klasy te zastępują stare, kłopotliwe klasy czasu i daty, takie jak java.util.Date, .Calendar, java.text.SimpleDateFormat.

Projekt Joda-Time, teraz w maintenance mode, zaleca migrację do java.time. Aby uzyskać więcej informacji, zobacz

. I wyszukaj Stack Overflow dla wielu przykładów i objaśnień.

Znaczna część funkcjonalności java.time powraca walcowy Java 6 & 7 w ThreeTen-Backport i ponadto dostosowany do Android w ThreeTenABP (patrz How to use…).

Projekt ThreeTen-Extra rozszerza java.time o dodatkowe klasy. Ten projekt jest poligonem wskazującym na możliwe przyszłe dodatki do java.time.

Powiązane problemy