Search code examples
javadate-parsinglocaltime

Java differences in parsed timestamps are ignored


In the following examples I succeeded to parse timestams in format yyMMddHHmmss(+-)HHss (a date plus or minus some time shift).

So, when I give two identical timestamps, and a different shift, the result should be different.

For example, let's take the datetime: 190219010000 (19th of February 2019, 01:00 [AM]), we can add 2 hours (the time will be 03:00) or subtract 2 hours (the time will be 23:00 and the date will be 18th of February) - that is, the parsed object should have 4 hours difference.

In the following, running example, the timeshift is ignored. I can write any number and the output is always "19th of February 2019, 01:00".

//Input timestamps: "190219010000+0200" "190219010000-0200"
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class HelloWorld
{
  public static void main(String[] args)
  { //parsing "19th of February 2019, 01:00 [AM]" +- 2hours
    LocalDateTime ldt1 = LocalDateTime.parse("190219010000+0200", DateTimeFormatter.ofPattern("yyMMddHHmmssx"));
    LocalDateTime ldt2 = LocalDateTime.parse("190219010000-0200", DateTimeFormatter.ofPattern("yyMMddHHmmssx"));
    System.out.println("190219010000+0200: " +ldt1);
    System.out.println("190219010000-0200: "+ ldt2);
  }
}

REAL output: in both cases the output is the same, but the input was different :/

190219010000+0200: 2019-02-19T01:00
190219010000-0200: 2019-02-19T01:00

Expected output:

190219010000+0200: 2019-02-19T03:00
190219010000-0200: 2019-02-18T23:00

Maybe I should use something else instead of the x in the pattern? Or a LocalDateTimeFormatter (that doesn't exist) instead of DateTimeFormatter?

Thanks


Solution

  • As others have said, you have misunderstood. In your code LocalDateTime.parse behaves as designed.

    You are correct that 190219010000+0200 is an unambiguous point in time (given that we know that the format is yyMMddHHmmssx). LocalDateTime.parse gives you the local date and time that is in the string. In other words, the local date and time at offset +02:00.

    If you want a conversion, for example to UTC, you need to specify that explicitly:

        OffsetDateTime odt1 = OffsetDateTime.parse("190219010000+0200", 
                DateTimeFormatter.ofPattern("yyMMddHHmmssx"));
        LocalDateTime ldt1 = odt1.withOffsetSameInstant(ZoneOffset.UTC)
                .toLocalDateTime();
    
        System.out.println("190219010000+0200: " + ldt1);
    

    Now the output is the one you expected. Almost.

    190219010000+0200: 2019-02-18T23:00

    As Jon Skeet already said +0200 generally means that a UTC offset of +02:00 has been applied to the date and time. So 01:00 at +02:00 is the same point in time as 23:00 on the previous day in UTC (if your strings are very special and apply the opposite convention for offsets, that can be solved too, but requires a little more hand work).