以UTC格式将LocalDateTime转换为LocalDateTime

135*_*355 57 java utc java-8 java-time

以UTC格式将LocalDateTime转换为LocalDateTime.

LocalDateTime convertToUtc(LocalDateTime date) {

    //do conversion

}
Run Code Online (Sandbox Code Playgroud)

我在网上搜索过.但没有得到解决方案

小智 75

我个人更喜欢

LocalDateTime.now(ZoneOffset.UTC);
Run Code Online (Sandbox Code Playgroud)

因为它是最易读的选择.

  • 这不是创造了一个新时代(现在)吗?最初的问题是将已知时间转换为 UTC (32认同)
  • 这不是所问问题的答案。 (10认同)

Leo*_*ley 73

有一种更简单的方法

LocalDateTime.now(Clock.systemUTC())
Run Code Online (Sandbox Code Playgroud)

  • 很好,但没有回答原来的问题. (9认同)
  • 此答案将 UTC 日期转换为 LocalDate。最初的问题是如何将 LocalDate 转换为 UTC 日期。 (4认同)

小智 38

LocalDateTime不包含区域信息.ZonedDatetime确实如此.

如果要将LocalDateTime转换为UTC,则需要按ZonedDateTime包装.

你可以像下面这样转换.

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());
Run Code Online (Sandbox Code Playgroud)

  • `ZoneOffset.UTC`是`ZoneI d.of("UTC")`的一个很好的替代品 (11认同)
  • 对于 UTC,`OffsetDateTime` 比 `ZonedDateTime` 更合适。使用:`OffsetDateTime.now( ZoneOffset.UTC )` 或 `myInstant.atOffset( ZoneOffset.UTC )` (3认同)
  • 这是正确的,虽然没有技术包装.`ldt.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneId.of("UTC"))`虽然简洁仍然传达了足够的意义,不需要分区实例变量. (2认同)

and*_*ero 14

题?

查看答案和问题,似乎问题已被显着修改。所以要回答当前的问题:

将 LocalDateTime 转换为 UTC 中的 LocalDateTime。

时区?

LocalDateTime不存储有关时区的任何信息,它只保存年、月、日、小时、分钟、秒和更小的单位的值。所以一个重要的问题是:原始的时区LocalDateTime什么它也可能已经是 UTC,因此不必进行转换。

系统默认时区

考虑到您无论如何都问了这个问题,您的意思可能是原始时间在您的系统默认时区中,并且您想将其转换为 UTC。因为通常一个LocalDateTime对象是通过使用LocalDateTime.now()which 返回系统默认时区中的当前时间来创建的。在这种情况下,转换将如下所示:

LocalDateTime convertToUtc(LocalDateTime time) {
    return time.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
}
Run Code Online (Sandbox Code Playgroud)

转换过程示例:

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
Run Code Online (Sandbox Code Playgroud)

显式时区

在任何其他情况下,当您明确指定要转换的时间的时区时,转换将如下所示:

LocalDateTime convertToUtc(LocalDateTime time, ZoneId zone) {
    return time.atZone(zone).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
}
Run Code Online (Sandbox Code Playgroud)

转换过程示例:

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
Run Code Online (Sandbox Code Playgroud)

atZone()方法

atZone()方法的结果取决于作为参数传递的时间,因为它考虑了时区的所有规则,包括夏令时 (DST)。在示例中,时间是 2 月 25 日,在欧洲,这意味着冬季时间(无 DST)。

如果我们使用不同的日期,假设是去年的 8 月 25 日,考虑到夏令时,结果会有所不同:

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
Run Code Online (Sandbox Code Playgroud)

GMT 时间不变。因此调整了其他时区的偏移量。在此示例中,爱沙尼亚的夏令时为 GMT+3,冬令时为 GMT+2。

此外,如果您在将时钟回退一小时的过渡期间指定时间。例如,2018 年 10 月 28 日 03:30 对于爱沙尼亚,这可能意味着两个不同的时间:

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]
Run Code Online (Sandbox Code Playgroud)

如果不手动指定偏移量(GMT+2 或 GMT+3),03:30时区的时间Europe/Tallinn可能意味着两个不同的 UTC 时间和两个不同的偏移量。

概括

如您所见,最终结果取决于作为参数传递的时间的时区。由于无法从LocalDateTime对象中提取时区,因此您必须自己知道它来自哪个时区才能将其转换为 UTC。

  • 感谢您提供有关 LocalDateTime 的信息,它不存储任何有关时区的信息!`LocalDateTime 不存储任何有关时区的信息,它基本上只保存年、月、日、小时、分钟、秒和更小的单位的值。 (2认同)

pat*_*elb 13

使用以下.它使用本地日期时间并使用时区将其转换为UTC.您不需要创建它的功能.

ZonedDateTime nowUTC = ZonedDateTime.now(ZoneOffset.UTC);
System.out.println(nowUTC.toString());
Run Code Online (Sandbox Code Playgroud)

如果需要获取ZonedDateTime的LocalDateTime部分,则可以使用以下内容.

nowUTC.toLocalDateTime();
Run Code Online (Sandbox Code Playgroud)

这是我在我的应用程序中使用的静态方法,用于在mysql中插入UTC时间,因为我无法将默认值UTC_TIMESTAMP添加到datetime列.

public static LocalDateTime getLocalDateTimeInUTC(){
    ZonedDateTime nowUTC = ZonedDateTime.now(ZoneOffset.UTC);

    return nowUTC.toLocalDateTime();
}
Run Code Online (Sandbox Code Playgroud)


Man*_*tra 10

这是一个简单的小实用程序类,可用于将本地日期时间从区域转换为区域,包括直接将实时方法从当前区域转换为UTC(使用main方法,以便您可以运行它并查看结果一个简单的测试):

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

public final class DateTimeUtil {
    private DateTimeUtil() {
        super();
    }

    public static void main(final String... args) {
        final LocalDateTime now = LocalDateTime.now();
        final LocalDateTime utc = DateTimeUtil.toUtc(now);

        System.out.println("Now: " + now);
        System.out.println("UTC: " + utc);
    }

    public static LocalDateTime toZone(final LocalDateTime time, final ZoneId fromZone, final ZoneId toZone) {
        final ZonedDateTime zonedtime = time.atZone(fromZone);
        final ZonedDateTime converted = zonedtime.withZoneSameInstant(toZone);
        return converted.toLocalDateTime();
    }

    public static LocalDateTime toZone(final LocalDateTime time, final ZoneId toZone) {
        return DateTimeUtil.toZone(time, ZoneId.systemDefault(), toZone);
    }

    public static LocalDateTime toUtc(final LocalDateTime time, final ZoneId fromZone) {
        return DateTimeUtil.toZone(time, fromZone, ZoneOffset.UTC);
    }

    public static LocalDateTime toUtc(final LocalDateTime time) {
        return DateTimeUtil.toUtc(time, ZoneId.systemDefault());
    }
}
Run Code Online (Sandbox Code Playgroud)


Hab*_*ade 6

用这个方法试试这个。

使用of方法将您转换LocalDateTime为并传递系统默认时区,或者您可以使用您的区域的ZoneId,例如ZonedDateTimeZoneId.of("Australia/Sydney");

LocalDateTime convertToUtc(LocalDateTime dateTime) {
  ZonedDateTime dateTimeInMyZone = ZonedDateTime.
                                        of(dateTime, ZoneId.systemDefault());

  return dateTimeInMyZone
                  .withZoneSameInstant(ZoneOffset.UTC)
                  .toLocalDateTime();
  
}
Run Code Online (Sandbox Code Playgroud)

要转换回您的区域本地日期时间,请使用:

LocalDateTime convertFromUtc(LocalDateTime utcDateTime){
    return ZonedDateTime.
            of(utcDateTime, ZoneId.of("UTC"))
            .toOffsetDateTime()
            .atZoneSameInstant(ZoneId.systemDefault())
            .toLocalDateTime();
}
Run Code Online (Sandbox Code Playgroud)


And*_*eng 5

tldr:根本没有办法做到这一点;如果你想这样做,你会得到LocalDateTime错误。

原因是LocalDateTime在创建实例后不记录时区。您不能将没有时区的日期时间转换为基于特定时区的另一个日期时间。

事实上,除非您的目的是获得随机结果,否则不应在生产代码中调用LocalDateTime.now()。当您像这样构造LocalDateTime实例时,此实例仅包含基于当前服务器时区的日期时间,这意味着如果这段代码运行具有不同时区配置的服务器,则会生成不同的结果。

LocalDateTime可以简化日期计算。如果您想要一个真正普遍可用的数据时间,请使用 ZonedDateTime 或 OffsetDateTime:https ://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html 。