Convert LocalDateTime to LocalDateTime in UTC

后端 未结 10 1012
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-30 08:20

Convert LocalDateTime to LocalDateTime in UTC.

LocalDateTime convertToUtc(LocalDateTime date) {

    //do conversion

}

I searched over net. Bu

相关标签:
10条回答
  • 2021-01-30 08:25

    Question?

    Looking at the answers and the question, it seems the question has been modified significantly. So to answer the current question:

    Convert LocalDateTime to LocalDateTime in UTC.

    Timezone?

    LocalDateTime does not store any information about the time-zone, it just basically holds the values of year, month, day, hour, minute, second, and smaller units. So an important question is: What is the timezone of the original LocalDateTime? It might as well be UTC already, therefore no conversion has to be made.

    System Default Timezone

    Considering that you asked the question anyway, you probably meant that the original time is in your system-default timezone and you want to convert it to UTC. Because usually a LocalDateTime object is created by using LocalDateTime.now() which returns the current time in the system-default timezone. In this case, the conversion would be the following:

    LocalDateTime convertToUtc(LocalDateTime time) {
        return time.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
    }
    

    An example of the conversion process:

    2019-02-25 11:39 // [time] original LocalDateTime without a timezone
    2019-02-25 11:39 GMT+1 // [atZone] converted to ZonedDateTime (system timezone is Madrid)
    2019-02-25 10:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
    2019-02-25 10:39 // [toLocalDateTime] losing the timezone information
    

    Explicit Timezone

    In any other case, when you explicitly specify the timezone of the time to convert, the conversion would be the following:

    LocalDateTime convertToUtc(LocalDateTime time, ZoneId zone) {
        return time.atZone(zone).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
    }
    

    An example of the conversion process:

    2019-02-25 11:39 // [time] original LocalDateTime without a timezone
    2019-02-25 11:39 GMT+2 // [atZone] converted to ZonedDateTime (zone is Europe/Tallinn)
    2019-02-25 09:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
    2019-02-25 09:39 // [toLocalDateTime] losing the timezone information
    

    The atZone() Method

    The result of the atZone() method depends on the time passed as its argument, because it considers all the rules of the timezone, including Daylight Saving Time (DST). In the examples, the time was 25th February, in Europe this means winter time (no DST).

    If we were to use a different date, let's say 25th August from last year, the result would be different, considering DST:

    2018-08-25 11:39 // [time] original LocalDateTime without a timezone
    2018-08-25 11:39 GMT+3 // [atZone] converted to ZonedDateTime (zone is Europe/Tallinn)
    2018-08-25 08:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
    2018-08-25 08:39 // [toLocalDateTime] losing the timezone information
    

    The GMT time does not change. Therefore the offsets in the other timezones are adjusted. In this example, the summer time of Estonia is GMT+3, and winter time GMT+2.

    Also, if you specify a time within the transition of changing clocks back one hour. E.g. October 28th, 2018 03:30 for Estonia, this can mean two different times:

    2018-10-28 03:30 GMT+3 // summer time [UTC 2018-10-28 00:30]
    2018-10-28 04:00 GMT+3 // clocks are turned back 1 hour [UTC 2018-10-28 01:00]
    2018-10-28 03:00 GMT+2 // same as above [UTC 2018-10-28 01:00]
    2018-10-28 03:30 GMT+2 // winter time [UTC 2018-10-28 01:30]
    

    Without specifying the offset manually (GMT+2 or GMT+3), the time 03:30 for the timezone Europe/Tallinn can mean two different UTC times, and two different offsets.

    Summary

    As you can see, the end result depends on the timezone of the time passed as an argument. Because the timezone cannot be extracted from the LocalDateTime object, you have to know yourself which timezone it is coming from in order to convert it to UTC.

    0 讨论(0)
  • 2021-01-30 08:27

    I personally prefer

    LocalDateTime.now(ZoneOffset.UTC);
    

    as it is the most readable option.

    0 讨论(0)
  • 2021-01-30 08:30

    Try this using this method.

    convert your LocalDateTime to ZonedDateTime by using the of method and pass system default time zone or you can use ZoneId of your zone like ZoneId.of("Australia/Sydney");

    LocalDateTime convertToUtc(LocalDateTime dateTime) {
      ZonedDateTime dateTimeInMyZone = ZonedDateTime.
                                            of(dateTime, ZoneId.systemDefault());
    
      return dateTimeInMyZone
                      .withZoneSameInstant(ZoneOffset.UTC)
                      .toLocalDateTime();
      
    }
    

    To convert back to your zone local date time use:

    LocalDateTime convertFromUtc(LocalDateTime utcDateTime){
        return ZonedDateTime.
                of(utcDateTime, ZoneId.of("UTC"))
                .toOffsetDateTime()
                .atZoneSameInstant(ZoneId.systemDefault())
                .toLocalDateTime();
    }
    
    0 讨论(0)
  • 2021-01-30 08:35

    LocalDateTime does not contain Zone information. ZonedDatetime does.

    If you want to convert LocalDateTime to UTC, you need to wrap by ZonedDateTime fist.

    You can convert like the below.

    LocalDateTime ldt = LocalDateTime.now();
    System.out.println(ldt.toLocalTime());
    
    ZonedDateTime ldtZoned = ldt.atZone(ZoneId.systemDefault());
    
    ZonedDateTime utcZoned = ldtZoned.withZoneSameInstant(ZoneId.of("UTC"));
    
    System.out.println(utcZoned.toLocalTime());
    
    0 讨论(0)
  • 2021-01-30 08:35

    tldr: there is simply no way to do that; if you are trying to do that, you get LocalDateTime wrong.

    The reason is that LocalDateTime does not record Time Zone after instances are created. You cannot convert a date time without time zone to another date time based on a specific time zone.

    As a matter of fact, LocalDateTime.now() should never be called in production code unless your purpose is getting random results. When you construct a LocalDateTime instance like that, this instance contains date time ONLY based on current server's time zone, which means this piece of code will generate different result if it is running a server with a different time zone config.

    LocalDateTime can simplify date calculating. If you want a real universally usable data time, use ZonedDateTime or OffsetDateTime: https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html.

    0 讨论(0)
  • 2021-01-30 08:38

    you can implement a helper doing something like that :

    public static LocalDateTime convertUTCFRtoUTCZ(LocalDateTime dateTime) {
        ZoneId fr = ZoneId.of("Europe/Paris");
        ZoneId utcZ = ZoneId.of("Z");
        ZonedDateTime frZonedTime = ZonedDateTime.of(dateTime, fr);
        ZonedDateTime utcZonedTime = frZonedTime.withZoneSameInstant(utcZ);
        return utcZonedTime.toLocalDateTime();
    }
    
    0 讨论(0)
提交回复
热议问题