2016-08-08 5 views
4

Warum ist es möglich, ein LocalDateTime Objekt in die ZonedDateTime.from() Methode zu übergeben, wenn es nicht möglich ist, eine einfache Datetime zu analysieren, wie folgt?Wie konvertiert man LocalDateTime in GregorianCalendar?

@Test 
public void test() throws Exception { 
    GregorianCalendar.from(ZonedDateTime.from(LocalDateTime.parse("2016-08-31T23:00:59"))); 
} 

Ergebnis:

java.time.DateTimeException: Unable to obtain ZonedDateTime from TemporalAccessor: 2016-08-31T23:00:59 of type java.time.LocalDateTime 
    at java.time.ZonedDateTime.from(ZonedDateTime.java:565) 
+1

Sind Sie fragen, wie zu einem 'GregorianCalendar' zu konvertieren, oder fragen Sie, warum es Ihnen erlaubt, ein zu übergeben Implementierung der 'TemporalAccessor'-Schnittstelle und klagt nur im Runtime darüber? – RealSkeptic

+2

GeorgianCalendar benötigt eine Zeitzone, also können Sie 'GregorianCalendar.from (ZonedDateTime.parse (" 2016-08-31T23: 00: 59 + 00: 00 "));' eine Zeitzone bereitstellen. 'ZonedDateTime.from' kann für verschiedene Eingabearten und die in javadoc genannten Arten fehlschlagen. – vsminkov

+1

Das Diagramm, das die Konvertierungen von alten Datum-Uhrzeit-Klassen in java.time in [meine Antwort] (http://stackoverflow.com/a/36639155) in [Java ju.time.Dat konvertieren zu dem Typ java.time] zeigt ?] (http://stackoverflow.com/q/36639154) kann nützlich sein. Finden Sie auch Beispielcode, der in beide Richtungen konvertiert. –

Antwort

4

Sie ZoneID auch zu bieten haben, ich werde auf das Verhalten zu sehen, warum dies ist, werde ich so schnell bearbeiten und veröffentlichen, wie ich sehe,

es
LocalDateTime ldt = LocalDateTime.parse("2016-08-31T23:00:59"); 
GregorianCalendar gc = GregorianCalendar.from(ZonedDateTime.of(ldt, ZoneId.systemDefault())); 
System.out.println(gc); 

Das Ergebnis:

java.util.GregorianCalendar [time = 1472664659000, areFieldsSet = tru e, areAllFieldsSet = true, lenient = true, zone = sun.util.calendar.ZoneInfo [id = "Asien/Kalkutta", Offset = 19800000, dstSavings = 0, useDaylight = false, Übergänge = 6, lastRule = null], firstDayOfWeek = 2, minimalDaysInFirstWeek = 4, ERA = 1, JAHR = 2016, MONAT = 7, WOCHE_DER_JAHR = 35, WOCHE_EIN_MONAT = 5, TAG_OF_MONAT = 31, TAG_OF_JAHR = 244, DAY_OF_WEEK = 4, DAY_OF_WEEK_IN_MONTH = 5, AM_PM = 1, STUNDE = 11 , HOUR_OF_DAY = 23, Minute = 0, SECOND = 59 Millisekunde = 0, ZONE_OFFSET = 19.800.000, DST_OFFSET = 0]

Edits Nur über diesen Thread kam (Unable to obtain ZonedDateTime from TemporalAccessor when parsing a Date)

Die Java 8 java.time. * Paket ist ein sehr striktes Paket. Es erlaubt keine Flexibilität zwischen Typen und Eingaben. Wenn Sie ein Objekt mit dem Namen "ZonedDateTime" erstellen möchten, müssen Sie es aus einer Eingabe mit einer Zeitzone erstellen, und zwar mit einem Datum & pro Zeit.

5

Warum ist es möglich, ein Local Objekt in den ZonedDateTime.from() -Methode übergeben, wenn es nicht möglich ist, eine einfache Datetime zu analysieren?

Sowohl LocalDateTimeZonedDateTime und implementiert die Schnittstelle Temporal, genannt, die TemporalAccessor erstreckt.

Local ist Datum-Zeit ohne eine Zeitzone in dem Systemkalender ISO-8601, wie 2007-12-03T10: 15: 30

ZonedDateTime ist Datum-Zeit mit einer Zeitzone in der ISO -8601 Kalendersystem, wie 2007-12-03T10: 15: 30 + 01: 00 Europa/Paris.

Jetzt, wenn Sie die Implementierung der from(TemporalAccessor temporal) Methode sehen, die die TemporalAccessor erwartet. Sowohl ZonedDateTime als auch LocalDateTime implementiert die Methode der Super-Schnittstelle TemporalAccessor (Temporal erweitert TemporalAccessor) es ist normal (polymorphes Verhalten), uns sowohl die lokale als auch die Zeitzone zu überlassen.

Code:

public static ZonedDateTime from(TemporalAccessor temporal) { 
      if (temporal instanceof ZonedDateTime) { 
       return (ZonedDateTime) temporal; 
      } 
      try { 
       ZoneId zone = ZoneId.from(temporal); 
       if (temporal.isSupported(INSTANT_SECONDS)) { 
        long epochSecond = temporal.getLong(INSTANT_SECONDS); 
        int nanoOfSecond = temporal.get(NANO_OF_SECOND); 
        return create(epochSecond, nanoOfSecond, zone); 
       } else { 
        LocalDate date = LocalDate.from(temporal); 
        LocalTime time = LocalTime.from(temporal); 
        return of(date, time, zone); 
       } 
      } catch (DateTimeException ex) { 
       throw new DateTimeException("Unable to obtain ZonedDateTime from TemporalAccessor: " + 
         temporal + " of type " + temporal.getClass().getName(), ex); 
      } 
     } 

Jetzt sind wir um Ihr Problem zu kommen.

Sie übergeben LocalDateTime.parse("2016-08-31T23:00:59") an die from(TemporalAccessor temporal) Methode.Das Temporal ist also keine Instanz von ZoneDateTime, es kommt ZoneId zone = ZoneId.from(temporal);

So erhalten Sie den Fehler, da die LocalDateTime die Zeitzone nicht enthält.

Wie löst man das Problem?

Verwenden Sie die Zone Id mit dem ZonedDateTime

LocalDateTime ldt = LocalDateTime.parse("2016-08-31T23:00:59"); 
ZoneId zoneId = ZoneId.of("Europe/Paris"); 
ZonedDateTime zdt = ldt.atZone(zoneId); 
GregorianCalendar gc = GregorianCalendar.from(zdt); 

Mit JUnit-Test

@Test 
public void test() throws Exception { 
    ZoneId zoneId = ZoneId.of("Europe/Paris"); 
    GregorianCalendar.from(LocalDateTime.parse("2016-08-31T23:00:59").atZone(zoneId)); 
} 
Verwandte Themen