2016-12-13 5 views
0

Die Art und Weise Java Zeit behandelt einfache Dinge wie Zeitstempel macht mich ein wenig verblüfft. Vielleicht mache ich es falsch.Java Zeit Instant Formatierung Diskrepanzen

Ich möchte eine ISO 8601 Timestamp-Zeichenfolge generieren. Der naheliegende Weg wäre, ein Instance.now() zu erstellen und es zu formatieren, verwenden Sie DateTimeFormatter.ISO_INSTANT, um es zu formatieren. Außer dass Instance keine format() Methode hat, kann ich es nicht mit dem Formatierer "instance" formatieren. Stell dir das vor.

Also muss ich eine ZonedDateTime aus der Instanz erstellen. Es sollte keine Rolle spielen, welche Zone ich wählen, so dass ich wählen UTC weil das ist, was DateTimeFormatter.ISO_INSTANT wird, um es in irgendeiner Weise:

Instant.now().atZone(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT) 

Jetzt bekomme ich einen String zurück, und natürlich will ich es ein zurück zu bekommen ZonedDateTime Beispiel, denn das habe ich mit dem Format formatiert! Also versuche ich:

ZonedDateTime.parse(timestamp, DateTimeFormatter.ISO_INSTANT) 

Es befindet sich auf mich beschwert, dass es keine Informationen Zeitzone ist. Aber ich habe eine ZonedDateTime verwendet, um es zu erzeugen --- es ist nicht meine Schuld, dass es mich nicht Instance verwenden ließ, um es zu formatieren.

Seltsamer Instance hat keine format() Methode, aber es hat eine parse() Methode, die wiederum seltsam, analysiert wird mit DateTimeFormatter.ISO_INSTANT (obwohl ich kann nicht Format ein Instance dass Formatierer verwenden).

Wie in den Kommentaren darauf hingewiesen, kann ich DateTimeFormatter.ISO_INSTANT.format(Instance.now()) verwenden, um eine Instanz direkt zu formatieren, also warum gibt es keine Instance.format(…)?

Also nur ein Timestamp zu generieren und zu analysieren scheint gefaltet und inkonsistent. Oder mache ich es falsch?

+1

Sie passieren kann 'Instant' zu' DateTimeFormatter.ISO_INSTANT.format (...) ', können Sie nicht? – lexicore

+0

Ah, in der Tat kann ich! Mir fehlte die gesamte 'DateTimeFormatter.format (...)' Methode. Dennoch ist es seltsam, dass 'Instant' keine' format (...) 'Methode hat, wenn es mit' DateTimeFormatter.format (...) 'arbeitet. Und dann wird das andere Problem sogar eine größere Inkonsistenz: Ich kann 'DateTimeFormatter.ISO_INSTANCE' verwenden, um eine' Instanz' zu formatieren, aber nicht um sie zurück zu analysieren! –

Antwort

-1

Warum müssen Sie den Formatierer beim Analysieren der Zeichenfolge neu festlegen? Können Sie nicht einfach ZonedDateTime.parse(timestamp); tun?

2

Zuerst können Sie nur DateTimeFormatter.ISO_INSTANT.format(Instant.now()).

Als nächstes sehe ich nicht, warum Sie erwarten, zu analysieren, was Sie formatiert haben. Formatierung ist nicht garantiert ein verlustfreier Vorgang. Wenn Sie ein LocalDateTime mit nur dem Jahr formatieren, würden Sie nicht erwarten, es zurück zu LocalDateTime zu analysieren, würden Sie?

Und natürlich können Sie Instant mit DateTimeFormatter.ISO_INSTANT analysieren. DateTimeFormatter.ISO_INSTANT.parse(text, Instant::from) - das ist was Instant.parse(...) tut.

+0

"Die Formatierung ist nicht garantiert ein verlustfreier Vorgang." Ich stimme einer allgemeinen Aussage zu, und ich möchte nicht streitsüchtig sein, aber was genau habe ich "verloren", als ich ein "Instant" nach ISO 8601 Timestamp format? Habe ich nicht 100% der Informationen, die benötigt werden, um das Original "Instant" zurück zu bekommen? (Ich kann es dir durch irgendeinen Code beweisen - irgendeinen gewundenen Code, was mein Punkt ist.) –

+0

Danke, dass du mich daran erinnerst, dass ich diese Zeitobjekte an 'DateTimeFormatter.format (...)' übergeben kann, so dass Teile davon entfernt werden die Diskrepanz. Aber viele der anderen, die ich erwähne, scheinen immer noch zu bleiben. –

+0

@GarretWilson Warte eine Sekunde, du hast kein 'Instant' formatiert, du hast' ZonedDateTime' formatiert und hast versucht, es mit 'ZonedDateTime' zu ​​analysieren. Und nicht nur das, sondern Sie haben auch das 'DateTimeFormatter.ISO_INSTANT' zum Parsen verwendet (hier verlieren Sie die Zeitzone). Also verstehe ich nicht, wie Sie darüber streiten können "Holen Sie das Original" Instant "zurück, da dies eindeutig nicht das ist, was Sie im Code machen. – lexicore

1

Es ist keine format(DateTimeFormatter) Methode in Instant erforderlich, weil toString() die Aufgabe erfüllt. Die toString() Methode von Instant implementiert als:

return DateTimeFormatter.ISO_INSTANT.format(this); 

So alles, was Sie tun müssen, um Anruf instant.toString().

Um Round-Trip analysieren diese wieder in, einfach parse() verwenden:

Instant instant = Instant.parse(text);