以UTC格式将LocalDateTime转换为LocalDateTime

问题描述 投票:50回答:9

以UTC格式将LocalDateTime转换为LocalDateTime。

LocalDateTime convertToUtc(LocalDateTime date) {

    //do conversion

}

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

java java-8 utc java-time
9个回答
73
投票

有一种更简单的方法

LocalDateTime.now(Clock.systemUTC())

65
投票

我个人更喜欢

LocalDateTime.now(ZoneOffset.UTC);

因为它是最易读的选择。


36
投票

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

12
投票

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

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

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

nowUTC.toLocalDateTime();

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

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

    return nowUTC.toLocalDateTime();
}

9
投票

这是一个简单的小实用程序类,可用于将本地日期时间从区域转换为区域,包括直接将实时方法从当前区域转换为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());
    }
}

2
投票

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

原因是LocalDateTime在创建实例后不记录时区。您无法根据特定时区将没有时区的日期时间转换为其他日期时间。

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

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


2
投票

题?

看看答案和问题,似乎问题已被大大修改。那么回答当前的问题:

以UTC格式将LocalDateTime转换为LocalDateTime。

时区?

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

系统默认时区

考虑到您无论如何都提出了问题,您可能意味着原始时间位于系统默认时区,并且您希望将其转换为UTC。因为通常使用LocalDateTime创建LocalDateTime.now()对象,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

转换过程的一个示例:

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

转换过程的一个示例:

atZone()

atZone()方法

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

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

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时间不会改变。因此,调整其他时区的偏移。在这个例子中,爱沙尼亚的夏令时是GMT + 3,冬天是GMT + 2。

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

03:30

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

摘要

如您所见,最终结果取决于作为参数传递的时间的时区。因为无法从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 对象中提取时区,所以您必须知道它来自哪个时区才能将其转换为UTC。


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

format.format(DT); }


-1
投票

你可以实现一个帮助器做这样的事情:

qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.