it-swarm.com.de

Konvertieren eines ISO 8601-kompatiblen Strings in Java.util.Date

Ich versuche einen ISO 8601 formatierten String in einen Java.util.Date umzuwandeln.

Ich habe festgestellt, dass das Muster yyyy-MM-dd'T'HH:mm:ssZ ISO8601-kompatibel ist, wenn es mit einem Gebietsschema verwendet wird (vergleiche Beispiel).

Mit dem Java.text.SimpleDateFormat kann ich jedoch den korrekt formatierten String 2010-01-01T12:00:00+01:00 nicht konvertieren. Ich muss es zuerst in 2010-01-01T12:00:00+0100 konvertieren, ohne den Doppelpunkt.

Die aktuelle Lösung ist also

SimpleDateFormat ISO8601DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.GERMANY);
String date = "2010-01-01T12:00:00+01:00".replaceAll("\\+0([0-9]){1}\\:00", "+0$100");
System.out.println(ISO8601DATEFORMAT.parse(date));

das ist natürlich nicht so schön. Vermisse ich etwas oder gibt es eine bessere Lösung?


Antwort

Dank JuanZes Kommentar fand ich die Joda-Zeit Magie, es ist auch hier beschrieben .

Die Lösung ist also

DateTimeFormatter parser2 = ISODateTimeFormat.dateTimeNoMillis();
String jtdate = "2010-01-01T12:00:00+01:00";
System.out.println(parser2.parseDateTime(jtdate));

Oder verwenden Sie einfach den Standardparser über den Konstruktor:

DateTime dt = new DateTime( "2010-01-01T12:00:00+01:00" ) ;

Für mich ist das schön.

613
Ice09

Leider sind die für SimpleDateFormat (Java 6 und früher) verfügbaren Zeitzonenformate nicht ISO 8601 kompatibel. SimpleDateFormat versteht Zeitzonenzeichenfolgen wie "GMT + 01: 00" oder "+0100", letzteres gemäß RFC # 822 .

Auch wenn Java 7 Unterstützung für Zeitzonendeskriptoren gemäß ISO 8601 hinzugefügt hat, kann SimpleDateFormat eine vollständige Datumszeichenfolge immer noch nicht richtig analysieren, da optionale Teile nicht unterstützt werden.

Das Neuformatieren Ihrer Eingabezeichenfolge mit Regexp ist sicherlich eine Möglichkeit, aber die Ersetzungsregeln sind nicht so einfach wie in Ihrer Frage:

  • Einige Zeitzonen haben keine vollen Arbeitsstunden UTC , sodass die Zeichenfolge nicht unbedingt mit ": 00" endet.
  • Nach ISO8601 kann nur die Anzahl der Stunden in der Zeitzone angegeben werden. "+01" entspricht also "+01: 00".
  • ISO8601 erlaubt die Verwendung von "Z", um UTC anstelle von "+00: 00" anzuzeigen.

Die einfachere Lösung besteht möglicherweise darin, den Datentypkonverter in JAXB zu verwenden, da JAXB in der Lage sein muss, die ISO8601-Datumszeichenfolge gemäß der XML-Schema-Spezifikation zu analysieren. javax.xml.bind.DatatypeConverter.parseDateTime("2010-01-01T12:00:00Z") gibt Ihnen ein Calendar Objekt und Sie können einfach getTime () verwenden, wenn Sie ein Date Objekt benötigen.

Sie könnten wahrscheinlich auch Joda-Time verwenden, aber ich weiß nicht, warum Sie sich darum kümmern sollten.

447
jarnbjo

Die Art, wie gesegnet durch Java 7 Dokumentation :

DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
String string1 = "2001-07-04T12:08:56.235-0700";
Date result1 = df1.parse(string1);

DateFormat df2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
String string2 = "2001-07-04T12:08:56.235-07:00";
Date result2 = df2.parse(string2);

Weitere Beispiele finden Sie im Abschnitt Beispiele unter SimpleDateFormat javadoc .

202
Antonio

Okay, diese Frage ist bereits beantwortet, aber ich werde meine Antwort trotzdem fallen lassen. Es könnte jemandem helfen.

Ich habe nach einer Lösung für Android (API 7) gesucht.

  • Joda kam nicht in Frage - es ist riesig und leidet unter langsamer Initialisierung. Es schien auch ein großer Overkill für diesen bestimmten Zweck.
  • Antworten mit javax.xml funktionieren nicht auf Android API 7.

Implementierung dieser einfachen Klasse beendet. Es behandelt nur die gebräuchlichste Form von ISO 8601-Zeichenfolgen, aber dies sollte in einigen Fällen ausreichen (wenn Sie sich ziemlich sicher sind, dass die Eingabe in dieser Form erfolgen wird) Format).

import Java.text.ParseException;
import Java.text.SimpleDateFormat;
import Java.util.Calendar;
import Java.util.Date;
import Java.util.GregorianCalendar;

/**
 * Helper class for handling a most common subset of ISO 8601 strings
 * (in the following format: "2008-03-01T13:00:00+01:00"). It supports
 * parsing the "Z" timezone, but many other less-used features are
 * missing.
 */
public final class ISO8601 {
    /** Transform Calendar to ISO 8601 string. */
    public static String fromCalendar(final Calendar calendar) {
        Date date = calendar.getTime();
        String formatted = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
            .format(date);
        return formatted.substring(0, 22) + ":" + formatted.substring(22);
    }

    /** Get current date and time formatted as ISO 8601 string. */
    public static String now() {
        return fromCalendar(GregorianCalendar.getInstance());
    }

    /** Transform ISO 8601 string to Calendar. */
    public static Calendar toCalendar(final String iso8601string)
            throws ParseException {
        Calendar calendar = GregorianCalendar.getInstance();
        String s = iso8601string.replace("Z", "+00:00");
        try {
            s = s.substring(0, 22) + s.substring(23);  // to get rid of the ":"
        } catch (IndexOutOfBoundsException e) {
            throw new ParseException("Invalid length", 0);
        }
        Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(s);
        calendar.setTime(date);
        return calendar;
    }
}

Performance note: Ich instanziiere jedes Mal ein neues SimpleDateFormat, um einen Fehler in Android 2.1 zu vermeiden. Wenn Sie so erstaunt sind wie ich, sehen Sie dieses Rätsel . Für andere Java Engines können Sie die Instanz in einem privaten statischen Feld zwischenspeichern (mit ThreadLocal, um threadsicher zu sein).

198
wrygiel

Java.time

Die Java.time API (integriert in Java 8 und höher) erleichtert dies ein wenig.

Wenn Sie wissen, dass sich die Eingabe in UTC befindet, z. B. die Klasse Z (für Zulu) am Ende, die Klasse Instant kann analysieren.

_Java.util.Date date = Date.from( Instant.parse( "2014-12-12T10:39:40Z" ));
_

Wenn es sich bei Ihrer Eingabe möglicherweise um einen anderen Versatz von UTC-Werten handelt, als um UTC , der durch Z (Zulu) auf dem angegeben wird Verwenden Sie am Ende die Klasse OffsetDateTime zum Parsen.

_OffsetDateTime odt = OffsetDateTime.parse( "2010-01-01T12:00:00+01:00" );
_

Dann extrahiere ein Instant und wandle es in ein Java.util.Date um, indem du from .

_Instant instant = odt.toInstant();  // Instant is always in UTC.
Java.util.Date date = Java.util.Date.from( instant );
_
92
Adam

Die Jackson-Datenbindungsbibliothek hat auch ISO8601DateFormat-Klasse , die dies tut (tatsächliche Implementierung in ISO8601Utils .

ISO8601DateFormat df = new ISO8601DateFormat();
Date d = df.parse("2010-07-28T22:25:51Z");
67
david_p

tl; dr

_OffsetDateTime.parse ( "2010-01-01T12:00:00+01:00" )
_

Java.time verwenden

Das neue Java.time -Paket in Java 8 und höher wurde von Joda-Time inspiriert.

Die Klasse OffsetDateTime repräsentiert einen Moment auf der Zeitachse mit einem Versatz-von-UTC , aber keiner Zeitzone.

_OffsetDateTime odt = OffsetDateTime.parse ( "2010-01-01T12:00:00+01:00" );
_

Durch Aufrufen von toString wird eine Zeichenfolge im Standardformat ISO 8601 generiert:

2010-01-01T12: 00 + 01: 00

Um den gleichen Wert durch die Linse von UTC zu sehen, extrahieren Sie ein Instant oder passen Sie den Versatz von _+01:00_ zu _00:00_ an.

_Instant instant = odt.toInstant();  
_

…oder…

_OffsetDateTime odtUtc = odt.withOffsetSameInstant( ZoneOffset.UTC );
_

Stellen Sie nach Wunsch eine Zeitzone ein. Eine Zeitzone ist ein Verlauf von Versatz-von-UTC Werten für eine Region mit einer Reihe von Regeln für die Behandlung von Anomalien wie Sommerzeit (DST). Wenden Sie daher nach Möglichkeit eine Zeitzone anstelle eines bloßen Versatzes an.

_ZonedDateTime zonedDateTimeMontréal = odt.atZoneSameInstant( ZoneId.of( "America/Montreal" ) );
_

Über Java.time

Das Java.time Framework ist in Java 8 und höher integriert. Diese Klassen ersetzen die lästigen alten Legacy Datum-Zeit-Klassen wie Java.util.Date , Calendar , & SimpleDateFormat =.

Das Joda-Time -Projekt, das sich jetzt im Wartungsmodus befindet, rät zur Migration auf Java.time = Klassen.

Weitere Informationen finden Sie im Oracle Tutorial . Durchsuchen Sie Stack Overflow nach vielen Beispielen und Erklärungen. Spezifikation ist JSR 31 .

Sie können Java.time Objekte direkt mit Ihrer Datenbank austauschen. Verwenden Sie einen JDBC-Treiber , der JDBC 4.2 oder höher entspricht. Keine Notwendigkeit für Zeichenfolgen, keine Notwendigkeit für _Java.sql.*_ Klassen.

Woher bekomme ich die Java.time-Klassen?

Das Projekt ThreeTen-Extra erweitert Java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Ergänzungen von Java.time. Hier finden Sie möglicherweise einige nützliche Klassen wie Interval , YearWeek , YearQuarter und more .


44
Basil Bourque

Für Java Version 7

Sie können der Oracle-Dokumentation folgen: http://docs.Oracle.com/javase/7/docs/api/Java/text/SimpleDateFormat.html

X - wird für die Zeitzone ISO 8601 verwendet

TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());

System.out.println(nowAsISO);

DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
//nowAsISO = "2013-05-31T00:00:00Z";
Date finalResult = df1.parse(nowAsISO);

System.out.println(finalResult);
27
d.danailov

Die DatatypeConverter-Lösung funktioniert nicht auf allen VMs. Folgendes funktioniert für mich:

javax.xml.datatype.DatatypeFactory.newInstance().newXMLGregorianCalendar("2011-01-01Z").toGregorianCalendar().getTime()

Ich habe festgestellt, dass Joda nicht sofort funktioniert (speziell für das Beispiel, das ich oben mit der Zeitzone für ein Datum angegeben habe, das gültig sein sollte).

20
James Scriven

Ich denke, wir sollten verwenden

DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")

für Datum 2010-01-01T12:00:00Z

15
Toby

Eine andere sehr einfache Methode zum Parsen von ISO8601-Zeitstempeln ist die Verwendung von org.Apache.commons.lang.time.DateUtils:

import static org.junit.Assert.assertEquals;

import Java.text.ParseException;
import Java.util.Date;
import org.Apache.commons.lang.time.DateUtils;
import org.junit.Test;

public class ISO8601TimestampFormatTest {
  @Test
  public void parse() throws ParseException {
    Date date = DateUtils.parseDate("2010-01-01T12:00:00+01:00", new String[]{ "yyyy-MM-dd'T'HH:mm:ssZZ" });
    assertEquals("Fri Jan 01 12:00:00 CET 2010", date.toString());
  }
}
9
tmandry

Die Problemumgehung für Java 7+ verwendet SimpleDateFormat:
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX", Locale.US);

Dieser Code kann das ISO8601-Format wie folgt analysieren:

  • 2017-05-17T06:01:43.785Z
  • 2017-05-13T02:58:21.391+01:00

Aber auf Java6 versteht SimpleDateFormat das Zeichen X nicht und wirft
IllegalArgumentException: Unknown pattern character 'X'
Wir müssen das ISO8601-Datum auf das in Java 6 lesbare Format mit SimpleDateFormat normalisieren.

public static Date iso8601Format(String formattedDate) throws ParseException {
    try {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX", Locale.US);
        return df.parse(formattedDate);
    } catch (IllegalArgumentException ex) {
        // error happen in Java 6: Unknown pattern character 'X'
        if (formattedDate.endsWith("Z")) formattedDate = formattedDate.replace("Z", "+0000");
        else formattedDate = formattedDate.replaceAll("([+-]\\d\\d):(\\d\\d)\\s*$", "$1$2");
        DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US);
        return df1.parse(formattedDate);
    }
}

Methode oben, um [Z durch +0000] oder [+01:00 durch +0100] zu ersetzen, wenn ein Fehler in Java 6 auftritt (Sie können Java versionieren und try/catch durch if Anweisung ersetzen.

6
Khang .NT

Java.time

Beachten Sie, dass Sie in Java 8 die Klasse Java.time.ZonedDateTime und die statische Methode parse(CharSequence text) verwenden können.

6
Martin Rust

Ich stellte das selbe Problem gegenüber und löste es durch den folgenden Code.

 public static Calendar getCalendarFromISO(String datestring) {
    Calendar calendar = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault()) ;
    SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault());
    try {
        Date date = dateformat.parse(datestring);
        date.setHours(date.getHours() - 1);
        calendar.setTime(date);

        String test = dateformat.format(calendar.getTime());
        Log.e("TEST_TIME", test);

    } catch (ParseException e) {
        e.printStackTrace();
    }

    return calendar;
}

Früher habe ich SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.getDefault()); verwendet

Aber später fand ich die Hauptursache für die Ausnahme war der yyyy-MM-dd'T'HH:mm:ss.SSSZ,

Also habe ich verwendet

SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault());

Es hat gut funktioniert für mich.

4
Abhay Kumar

Sie können auch die folgende Klasse verwenden -

org.springframework.extensions.surf.util.ISO8601DateFormat


Date date = ISO8601DateFormat.parse("date in iso8601");

Link zum Java Doc - Hierarchie für Paket org.springframework.extensions.surf.maven.plugin.util

4
Sergey Palyukh

Wie andere bereits erwähnt haben, bietet Android keine gute Möglichkeit, das Parsen/Formatieren von ISO 8601-Daten mithilfe von im SDK enthaltenen Klassen zu unterstützen. Ich habe diesen Code mehrmals geschrieben, also habe ich endlich eine Gist erstellt, die eine DateUtils-Klasse enthält, die das Formatieren und Parsen von ISO 8601- und RFC 1123-Daten unterstützt. Der Gist enthält auch einen Testfall, der zeigt, was er unterstützt.

https://Gist.github.com/mraccola/702330625fad8eebe7d

3
Matt Accola

Apache Jackrabbit verwendet das ISO 8601-Format zum Speichern von Datumsangaben, und es gibt eine Hilfsklasse, um diese zu analysieren:

org.Apache.jackrabbit.util.ISO8601

Kommt mit Jackrabbit-JCR-Commons .

Java hat ein Dutzend verschiedene Möglichkeiten, eine Datums- und Uhrzeitangabe zu analysieren, wie die hervorragenden Antworten hier zeigen. Aber erstaunlicherweise implementiert keine von Javas Zeitklassen ISO 8601 vollständig!

Mit Java 8 würde ich empfehlen:

ZonedDateTime zp = ZonedDateTime.parse(string);
Date date = Date.from(zp.toInstant());

Dies behandelt Beispiele sowohl in UTC als auch mit einem Versatz wie "2017-09-13T10: 36: 40Z" oder "2017-09-13T10: 36: 40 + 01: 00". Dies ist für die meisten Anwendungsfälle ausreichend.

Beispiele wie "2017-09-13T10: 36: 40 + 01", bei denen eine gültige ISO 8601-Datumszeit ist , werden jedoch nicht verarbeitet.
Es wird auch nicht nur das Datum behandeln, z. "2017-09-13".

Wenn Sie damit umgehen müssen, würde ich vorschlagen, zuerst einen regulären Ausdruck zu verwenden, um die Syntax zu ermitteln.

Hier finden Sie eine schöne Liste von ISO 8601-Beispielen mit vielen Eckfällen: https://www.myintervals.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck / Ich kenne keine Klasse Java, die mit allen zurechtkommt.

2

SimpleDateFormat für Java 1.7 hat ein cooles Muster für das ISO 8601-Format.

Klasse SimpleDateFormat

Folgendes habe ich getan:

Date d = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SSSZ",
         Locale.ENGLISH).format(System.currentTimeMillis());
2
Eesha

Mach es so:

public static void main(String[] args) throws ParseException {

    String dateStr = "2016-10-19T14:15:36+08:00";
    Date date = javax.xml.bind.DatatypeConverter.parseDateTime(dateStr).getTime();

    System.out.println(date);

}

Hier ist die Ausgabe:

Mi 19 Okt 15:15:36 CST 2016

1
yinhaomin

Verwenden Sie einen String wie LocalDate.parse(((String) data.get("d_iso8601")),DateTimeFormatter.ISO_DATE)

1
Stepan

Ich bin überrascht, dass nicht einmal eine Java Bibliothek alle ISO 8601-Datumsformate gemäß https://en.wikipedia.org/wiki/ISO_8601 unterstützt. Joda DateTime unterstützte die meisten von ihnen, aber nicht alle, und daher fügte ich benutzerdefinierte Logik hinzu, um mit allen umzugehen. Hier ist meine Implementierung.

import Java.text.ParseException;
import Java.util.Date;

import org.Apache.commons.lang3.time.DateUtils;
import org.joda.time.DateTime;

public class ISO8601DateUtils {
        
        /**
         * It parses all the date time formats from https://en.wikipedia.org/wiki/ISO_8601 and returns Joda DateTime.
         * Zoda DateTime does not support dates of format 20190531T160233Z, and hence added custom logic to handle this using SimpleDateFormat.
         * @param dateTimeString ISO 8601 date time string
         * @return
         */
        public static DateTime parse(String dateTimeString) {
                try {
                        return new DateTime( dateTimeString );
                } catch(Exception e) {
                        try {
                                Date dateTime = DateUtils.parseDate(dateTimeString, JODA_NOT_SUPPORTED_ISO_DATES);
                                return new DateTime(dateTime.getTime());
                        } catch (ParseException e1) {
                                throw new RuntimeException(String.format("Date %s could not be parsed to ISO date", dateTimeString));
                        }
                }
        }
  
        private static String[] JODA_NOT_SUPPORTED_ISO_DATES = new String[] {
                        // upto millis
                        "yyyyMMdd'T'HHmmssSSS'Z'",
                        "yyyyMMdd'T'HHmmssSSSZ",
                        "yyyyMMdd'T'HHmmssSSSXXX",
                        
                        "yyyy-MM-dd'T'HHmmssSSS'Z'",
                        "yyyy-MM-dd'T'HHmmssSSSZ",
                        "yyyy-MM-dd'T'HHmmssSSSXXX",
                        
                        // upto seconds
                        "yyyyMMdd'T'HHmmss'Z'",
                        "yyyyMMdd'T'HHmmssZ",
                        "yyyyMMdd'T'HHmmssXXX",
                        
                        "yyyy-MM-dd'T'HHmmss'Z'", 
                        "yyyy-MM-dd'T'HHmmssZ",
                        "yyyy-MM-dd'T'HHmmssXXX",
                        
                        // upto minutes
                        "yyyyMMdd'T'HHmm'Z'",
                        "yyyyMMdd'T'HHmmZ",
                        "yyyyMMdd'T'HHmmXXX",

                        "yyyy-MM-dd'T'HHmm'Z'",
                        "yyyy-MM-dd'T'HHmmZ",
                        "yyyy-MM-dd'T'HHmmXXX",
                        
                        //upto hours is already supported by Joda DateTime
        };
}
0
raok1997

Ich hatte ein ähnliches Bedürfnis: Ich musste in der Lage sein, jedes ISO8601-konforme Datum zu analysieren, ohne das genaue Format im Voraus zu kennen, und ich wollte eine leichte Lösung, die auch auf Android funktionieren würde.

Als ich meine Bedürfnisse googelte, stieß ich auf diese Frage und stellte fest, dass AFAIU, keine Antwort vollständig meinen Bedürfnissen entsprach. Also entwickelte ich jISO8601 und schob es auf maven central.

Füge einfach pom.xml hinzu:

<dependency>
  <groupId>fr.turri</groupId>
  <artifactId>jISO8601</artifactId>
  <version>0.2</version>
</dependency>

und dann kann es losgehen:

import fr.turri.jiso8601.*;
...
Calendar cal = Iso8601Deserializer.toCalendar("1985-03-04");
Date date = Iso8601Deserializer.toDate("1985-03-04T12:34:56Z");

Hoffe es hilft.

0
gturri

Um ein Datum wie dieses zu formatieren, funktionierte das Folgende für mich in einer Java 6-basierten Anwendung. Es gibt eine DateFormat Klasse JacksonThymeleafISO8601DateFormat im Thymeleaf-Projekt, die den fehlenden Doppelpunkt einfügt:

https://github.com/thymeleaf/thymeleaf/blob/40d27f44df7b52eda47d1bc6f1b3012add6098b3/src/main/Java/org/thymeleaf/standard/serializer/StandardJavaScriptSerializer.Java

Ich habe es für die Kompatibilität des ECMAScript-Datumsformats verwendet.

0
ekip

Ein kleiner Test, der zeigt, wie ein Datum in ISO8601 analysiert wird und LocalDateTime DSTs nicht verarbeitet.

 @Test
    public void shouldHandleDaylightSavingTimes() throws ParseException {

        //ISO8601 UTC date format
        SimpleDateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");

        // 1 hour of difference between 2 dates in UTC happening at the Daylight Saving Time
        Date d1 = utcFormat.parse("2019-10-27T00:30:00.000Z");
        Date d2 = utcFormat.parse("2019-10-27T01:30:00.000Z");

        //Date 2 is before date 2
        Assert.assertTrue(d1.getTime() < d2.getTime());
        // And there is 1 hour difference between the 2 dates
        Assert.assertEquals(1000*60*60, d2.getTime() - d1.getTime());

        //Print the dates in local time
        SimpleDateFormat localFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm z Z", Locale.forLanguageTag("fr_CH"));
        localFormat.setTimeZone(TimeZone.getTimeZone("Europe/Zurich"));

        //Both dates are at 02h30 local time (because of DST), but one is CEST +0200 and the other CET +0100 (clock goes backwards)
        Assert.assertEquals("2019-10-27 02:30 CEST +0200", localFormat.format(d1));
        Assert.assertEquals("2019-10-27 02:30 CET +0100", localFormat.format(d2));

        //Small test that shows that LocalDateTime does not handle DST (and should not be used for storing timeseries data)
        LocalDateTime ld1 = LocalDateTime.ofInstant(d1.toInstant(), ZoneId.of("Europe/Zurich"));
        LocalDateTime ld2 = LocalDateTime.ofInstant(d2.toInstant(), ZoneId.of("Europe/Zurich"));

        //Note that a localdatetime does not handle DST, therefore the 2 dates are the same
        Assert.assertEquals(ld1, ld2);

        //They both have the following local values
        Assert.assertEquals(2019, ld1.getYear());
        Assert.assertEquals(27, ld1.getDayOfMonth());
        Assert.assertEquals(10, ld1.getMonthValue());
        Assert.assertEquals(2, ld1.getHour());
        Assert.assertEquals(30, ld1.getMinute());
        Assert.assertEquals(0, ld1.getSecond());

    }
0
ddtxra