在UTC中将LocalDateTime转换为LocalDateTime


82

在UTC中将LocalDateTime转换为LocalDateTime。

LocalDateTime convertToUtc(LocalDateTime date) {

    //do conversion

}

我在网上搜索。但是没有解决办法


4
您是否找到LocalDateTime的javadoc?它说:“该类不存储或表示时区。相反,它是对用于生日的日期的描述,并结合在墙上时钟上看到的本地时间。它不能表示时标。时间轴,而没有其他信息,例如偏移量或时区。”
aro_tech '16

1
您的问题没有道理-您应该说明此方法的上下文以及您要实现的目标。您似乎对API的各种类代表什么有基本的误解。
assylias

3
如果您关心时区,则需要使用ZonedDateTime,它具有在时区withZoneSameLocal()和withZoneSameInstant()之间进行转换的方法
JodaStephen

嗯 我明白了 谢谢
Sarika.S 2016年

Answers:


103

我个人更喜欢

LocalDateTime.now(ZoneOffset.UTC);

因为它是最易读的选项。


19
这不是在创造新的时间(现在)吗?最初的问题是关于将已知时间转换为UTC
Evvo


57

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

2
这是正确的,尽管在技术上没有包装。ldt.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneId.of("UTC"))尽管简洁仍然传达了足够的含义,不需要分区实例变量。
Brett Ryan

19
ZoneOffset.UTCZoneI‌​d.of("UTC")
ycomp

2
对于UTC的OffsetDateTime比更合适ZonedDateTime。使用:OffsetDateTime.now( ZoneOffset.UTC )myInstant.atOffset( ZoneOffset.UTC )
罗勒·布尔克

15

使用以下内容。它采用本地日期时间,并使用时区将其转换为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();
}

14

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

还添加:final LocalDateTime backToLocal = DateTimeUtil.toZone(utc,ZoneOffset.UTC,ZoneId.systemDefault()); System.out.println(“返回本地:” + backToLocal);
rjdkolb

7

题?

查看答案和问题,似乎问题已得到重大修改。因此,要回答当前问题:

在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()方法的结果取决于作为其参数传递的时间,因为它考虑了时区的所有规则,包括夏时制(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时间不变。因此,可以调整其他时区的偏移量。在此示例中,爱沙尼亚的夏季时间为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)的情况03:30下,时区的时间Europe/Tallinn可以表示两个不同的UTC时间和两个不同的偏移量。

概要

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


1
感谢您提供有关LocalDateTime的信息,其中不存储有关时区的任何信息!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.
刘文斌

5

tldr:根本没有办法做到;如果您尝试执行此操作,则会得到LocalDateTime错误。

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

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

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


LocalDateTime不会记录时区,但是您可能从其他地方获得了此知识,并在转换之前将此信息添加到LocalDateTimes中。
特里斯坦,

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

UTC到UTC Z?没什么意思。UTC = Z,UTC <> fr
Tristan

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


1
请不要教年轻的孩子们使用已经过时且臭名昭著的SimpleDateFormat课程。至少不是第一选择。也并非毫无保留。今天,我们java.time在现代Java日期和时间API及其功能方面有了很多改进DateTimeFormatter
Ole VV
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.