Mikrosekunden
Ihr Fragetext zitiert die Eingabezeichenfolge als 2016-05-14 12:54:01.363
, aber Ihre Fehlermeldung sagt andernfalls 2016-05-14 12:54:01.363000
. Diese zusätzlichen drei Ziffern sind microseconds.
Die alten Datum/Uhrzeit-Klassen wie java.util.Date werden nur auf milliseconds aufgelöst (3 Nachkommastellen für Sekundenbruchteile). So SimpleDateFormat
kann nicht mit solchen Eingaben umgehen. Entweder die Eingabezeichenfolge abschneiden oder stattdessen moderne Datums-/Uhrzeitklassen verwenden.
java.time
Das größere Problem ist, dass Sie alte veraltete Datum Zeitklassen von den frühesten Versionen von Java verwenden. Diese Klassen wurden durch das in Java 8 und höher integrierte Framework java.time ersetzt. Viel von dieser java.time-Funktionalität wurde durch das ThreeTen-Backport Projekt in Java 6 & 7 zurück portiert und weiter an Android von ThreeTenABP angepasst. Also kein Grund, mit diesen alten und notorisch lästigen Klassen zu ringen.
Die java.time-Klassen haben eine viel feinere Granularität und werden in nanoseconds aufgelöst (9 Dezimalstellen der Sekunden).
In java.time ist die Klasse Instant
ein Moment auf der Timeline in UTC mit einer Auflösung von Nanosekunden. Ein Instant
ist das Äquivalent zu einem java.util.Date
, außer mit feinerer Auflösung.
Für weitere Informationen über die Konvertierung zwischen alten Typen und Java.Zeittypen, siehe my Answer with diagram zu einer anderen Frage.
abrufen Datum Zeitwert als Datum Zeittyp
Sie sollten Datum Zeitwert aus der Datenbank als Datum-Zeit-Typen, nicht als Strings werden abruft. Wenn Ihr JDBC-Treiber JDBC 4.2 entspricht (ein Update auf JSR 221 und described here), können Sie möglicherweise direkt in eine OffsetDateTime
abrufen. Sie können sich eine OffsetDateTime
als Instant
plus eine offset-from-UTC (eine Anzahl Stunden, Minuten und Sekunden) vorstellen.
Wenn nicht, greifen Sie auf die alten java.sql Typen zurück. Für Datum-Uhrzeit bedeutet das java.sql.Timestamp
.
java.sql.Timestamp ts = resultSet.getTimestamp(1);
Minimieren Sie Ihre Nutzung der alten java.sql Typen, wie sie Teil des Chaos sind die java.util.Date/.Calendar ist und so weiter. Sofort in java.time konvertieren. Suchen Sie zum Konvertieren nach neuen Methoden, die zu den alten Klassen hinzugefügt wurden, z. B. toInstant
.
Instant instant = ts.toInstant();
Parsing
Wenn Sie diese Eingabezeichenfolge analysieren muss, ist der einfachste Weg, um es mit den ISO 8601 Standardformate zu machen entsprechen. Die Klassen java.time verwenden beim Analysieren/Erzeugen von Strings standardmäßig ISO 8601-Formate.
Um die Anforderungen zu erfüllen, ersetzen Sie den RAUM in der Mitte mit einem T
. Und angenommen, diese Zeichenfolge stellt tatsächlich einen Moment in UTC dar, fügen Sie eine Z
hinzu. Die Z
ist die Abkürzung für Zulu
, was UTC bedeutet.
String input = "2016-05-14 12:54:01.363000";
String inputModified = input.replace(" " , "T");
Instant instant = Instant.parse(inputModified);
Zeitzone
Die Frage ignoriert die entscheidende Frage der Zeitzonen.
Die beste Vorgehensweise besteht darin, Datums- und Uhrzeitwerte in UTC zu speichern. Die besseren Datenbanken passen eingehende Daten in UTC an. Wenn der Wert als java.sql.Timestamp
abgerufen wird, ist Ihr Wert in UTC und auch in Instant
konvertiert.
Ein Datum und eine Uhrzeit hängen von der Zeitzone ab. Wenden Sie eine Zeitzone (ZoneId
) auf Ihre Instant
an, um eine ZonedDateTime
zu erhalten.
ZoneId zoneId = zoneId.of("America/Montreal");
ZonedDateTime zdt = ZonedDateTime.ofInstant(instant , zoneId);
Dann fragen Sie den Tag des Monats und die Zeit, die Sie benötigen.
int dayOfMonth = zdt.getDayOfMonth();
Wenn Sie die Zeit-of-Tag als ein Objekt in seinem eigenen Recht, verwenden Sie die LocalTime
Klasse.
LocalTime localTime = zdt.toLocalTime();
Wenn Sie wirklich ein String der Time-of-Tag, verwenden Sie die java.time.format Paket.
Noch besser, lassen Sie java.time die Arbeit der automatischen Formatierung erledigen.Beachten Sie die Verwendung von Locale, die (a) die menschliche Sprache für den Namen des Monats und so definiert, und (b) kulturelle Normen wie die Reihenfolge der Elemente wie Jahr-Monat-Tag. Besser, das Gebietsschema explizit anzugeben, als sich implizit auf das aktuelle Standardgebietsschema der JVM zu verlassen, das sich zur Laufzeit ändern kann.
DateTimeFormatter timeOfDayFormatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);
timeOfDayFormatter = timeOfDayFormatter.withLocale(Locale.CANADA_FRENCH);
String output = zdt.toLocalTime().format(timeOfDayFormatter);
Bitte suchen Sie vor dem Posten Stack Overflow. –
@BasilBourque Ihre Markierung als Duplikat führt mich nicht zu meiner Antwort, weil ich einen Fehler von ** Unrated Datum bekomme: "{" Datum ":" 2016-05-14 12: 54: 01.363000 "," Zeitzone ":" UTC "," timezone_type ": 3}" ** nicht ** java.text.ParseException: Nicht übertragbares Datum: "2015-03-26 1624: 32: 39" **. Heben Sie die Markierung dieser Frage als Duplikat auf. –
[A] Du hast Recht, du Frage ist kein Duplikat dieser speziellen Frage, also habe ich sie wieder geöffnet. Aber es ist ein Duplikat von anderen. [B] Ihr zitiertes Ergebnis im ersten Absatz ist * nicht * das tatsächliche Vergehen. Sie haben die zusätzlichen drei Nullen am Ende weggelassen, was die Ursache Ihres Problems ist. Bitte bearbeiten Sie Ihre Frage, um korrekt zu sein. [C] Du hast zu viel Code, irrelevanten Code gepostet. Nur die zwei 'format =' und 'date =' Zeilen sind relevant. Stellen Sie beim Verfassen ein [minimales, vollständiges und überprüfbares Beispiel] (http://stackoverflow.com/help/mcve) bereit. –