Search code examples
javatimezonejodatime

From String without timezone to time with Europe/Berlin


I've tried the whole day to parse a date, which I've got from a System as a String without Timezone to a String with Timezone and applied time difference

Original String: "01/27/2021 14:47:29"

Target String: "2021-01-27T13:47:29.000+01:00"

Problem: The target System can not change the format. I need to apply, that it substracts automatically the correct amount of hours, depending on summer/winter time. So it's not a solution to just subtract -1.

I've tried with several This is my last try which is almost correct, but it does not change the hours correctly:

DateTimeFormatter fmt = DateTimeFormat.forPattern("MM/dd/yyyy HH:mm:ss").withZone(DateTimeZone.forID(
                "Europe/Berlin"));
DateTime dt = fmt.parseDateTime(lastModifid);
dt.toString()

Result is "2021-01-27T14:47:29.000+01:00"

Isn't there an easy solution to apply these time differences?


Solution

  • java.time

    I am just spelling out the good suggestion by hfontanez a little bit more. I am first declaring:

    private static final DateTimeFormatter formatter
            = DateTimeFormatter.ofPattern("MM/dd/uuuu HH:mm:ss");
    private static final ZoneId targetZone = ZoneId.of("Europe/Berlin");
    

    Then processing your string goes like this:

        String originalString = "01/27/2021 14:47:29";
        
        OffsetDateTime dateTime = LocalDateTime.parse(originalString, formatter)
                .atOffset(ZoneOffset.UTC);
        String targetString = dateTime.atZoneSameInstant(targetZone)
                .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
        
        System.out.println(targetString);
    

    And output is:

    2021-01-27T15:47:29+01:00

    You asked for 13:47:29.000 and I gave you 15:47:29. Why?

    • I assumed that the original string was in UTC, so in the code I explicitly told Java to interpret it in this way. If this assumption is correct, then it seems that you have misunderstood. The offsets for German time (Europe/Berlin), standard +01:00 and +02:00 during summer time (DST), mean that Germany is 1 or 2 hours ahead of UTC, so we need to add, not subtract, 1 or 2 hours. And as hfontanez already said, the library is doing it correctly for us.
    • The format you asked for and that Joda-Time produces too is ISO 8601. According to ISO 8601 the decimals on the seconds are optional when they are zero, so for your purpose you should not need the .000 part of the target string.

    Like hfontanez I am using java.time, the modern Java date and time API. Why? I consider java.time the good successor of Joda-Time. The Joda-Time homepage itself says (boldface is original):

    Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.

    What went wrong in your code?

    You were applying .withZone(DateTimeZone.forID("Europe/Berlin")) to the formatter that you used for parsing your original string. This is the same as telling Joda-Time that the original string is already in German time. So from that Joda-Time decides that no conversion of the time is necessary and just gives you the same hour of day back. Instead we first need to specify in which time zone the original string is and then convert it to German time.

    Links