以 UTC 格式将 LocalDateTime 转换为 LocalDateTime

以 UTC 格式将 LocalDateTime 转换为 LocalDateTime。

LocalDateTime convertToUtc(LocalDateTime date) {


//do conversion


}

我在网上搜索。但没有得到一个解决方案

233683 次浏览

使用下面的代码。它获取本地日期时间并使用时区将其转换为 UTC。您不需要创建它的函数。

ZonedDateTime nowUTC = ZonedDateTime.now(ZoneOffset.UTC);
System.out.println(nowUTC.toString());

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

nowUTC.toLocalDateTime();

Here is a static method i use in my application to insert UTC time in mysql since i cannot add a default value UTC _ TIMESTAMP to a datetime column.

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


return nowUTC.toLocalDateTime();
}

还有一个更简单的方法

LocalDateTime.now(Clock.systemUTC())

LocalDateTime 不包含 Zone 信息,而 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());

Tldr: 根本没有办法做到这一点; 如果你试图这样做,你得到的 本地日期时间是错误的。

原因是 本地日期时间在创建实例后不记录时区。无法根据特定时区将没有时区的日期时间转换为另一个日期时间。

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

LocalDateTime 可以简化日期计算。

public static String convertFromGmtToLocal(String gmtDtStr, String dtFormat, TimeZone lclTimeZone) throws Exception{
if (gmtDtStr == null || gmtDtStr.trim().equals("")) return null;
SimpleDateFormat format = new SimpleDateFormat(dtFormat);
format.setTimeZone(getGMTTimeZone());
Date dt = format.parse(gmtDtStr);
format.setTimeZone(lclTimeZone);
return

format.format(dt); }

你可以实现一个助手来做类似的事情:

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();
}

I personally prefer

LocalDateTime.now(ZoneOffset.UTC);

因为它是最可读的选项。

这里有一个简单的实用工具类,你可以使用它将本地日期时间从一个区域转换到另一个区域,包括一个实用工具方法,它可以直接将当前区域的本地日期时间转换为 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());
}
}

有问题吗?

看看这些答案和这个问题,似乎这个问题已经被显著地修改了。现在回答这个问题:

以 UTC 格式将 LocalDateTime 转换为 LocalDateTime。

Timezone?

LocalDateTime不存储任何关于时区的信息,它基本上只存储年、月、日、小时、分钟、秒和更小的单位的值。所以一个重要的问题是: LocalDateTime的时区是多少?它可能已经是 UTC 了,因此不需要进行转换。

系统默认时区

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

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

转换过程的一个例子:

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

显式时区

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();
}

转换过程的一个例子:

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

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

如果我们使用一个不同的日期,比如说去年的8月25日,结果就会不同,考虑到 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

格林尼治标准时间不变。因此调整了其他时区的偏移量。在这个例子中,爱沙尼亚的夏季时间是 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]

不需要手动指定偏移量(GMT + 2或 GMT + 3) ,时区 Europe/Tallinn的时间 03:30可以表示两个不同的 UTC 时间和两个不同的偏移量。

摘要

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

使用此方法尝试执行此操作。

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

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


return dateTimeInMyZone
.withZoneSameInstant(ZoneOffset.UTC)
.toLocalDateTime();
  

}

转换回您的区域当地日期时间使用:

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