【问题标题】:How to get OffsetDateTime->LocalDateTime and save this as UTC?如何获取 OffsetDateTime->LocalDateTime 并将其保存为 UTC?
【发布时间】:2020-04-27 20:48:19
【问题描述】:

即使经过大量搜索,我也没有找到适合我的问题的答案。 它是 Java API 中的 DateConvertUtil 类。 这是一种重构/功能任务。

我有一个方法,它解析一个给定的日期字符串,在另一个方法的帮助下格式化它并返回一个 LocalDateTime(这有点 - 依赖太多了)。

我想获取用户的时区,转换(或者可能不)转换为 LocalDateTime 但不想每次都保存 LocalDateTime 而是 UTC。

我现在的问题是如何解决这个问题。 我似乎没有得到偏移量。

解析器以前可以工作,但仅适用于 LocaldateTime,格式化程序也可以工作。

到现在为止

    public static LocalDateTime parseIso8601(String date) {
        if (date == null || date.isEmpty() || date.trim().equalsIgnoreCase("") || date.length() < 10) throw new
                IllegalArgumentException("Date cannot by empty or smaller than 10 characters for parsing! Minimum date " +
                "is yyyy-MM-dd");


        LocalDateTime localDateTime;
        OffsetDateTime offsetDateTime = OffsetDateTime.now();
        offsetDateTime.toInstant().atZone(ZoneOffset.UTC);

        localDateTime = offsetDateTime.toLocalDateTime();

        return localDateTime.parse(date, buildIso8601Formatter());

所以我已经阅读了一些关于 ZonedDateTime 和 Timestamps 的内容,但也许我只是想不通。

感谢您的帮助。

【问题讨论】:

    标签: java parsing utc datetimeoffset localdate


    【解决方案1】:

    不是很清楚。您可能会追求以下内容:

        ZoneId userTimeZone = ZoneId.systemDefault();
    
        String date = "2019-12-25";
    
        LocalDateTime localDateTime = LocalDate.parse(date).atStartOfDay();
        System.out.println("localDateTime: " + localDateTime);
    
        OffsetDateTime utcDateTime = localDateTime.atZone(userTimeZone)
                .toOffsetDateTime()
                .withOffsetSameInstant(ZoneOffset.UTC);
        System.out.println("utcDateTime: " + utcDateTime);
    

    当我在我的时区(欧洲/哥本哈根)运行这个 sn-p 时,输出是:

    localDateTime: 2019-12-25T00:00
    utcDateTime: 2019-12-24T23:00Z
    

    你说:

    我想获取用户的时区,...

    执行此操作的方式不同。在独立应用程序中,您可以尝试ZonedId.systemDefault(),如上述代码所示。它为您提供 JVM 的默认时区,该时区可能与用户的意图一致,也可能不一致。并且可以随时从程序的另一部分或在同一 JVM 中运行的另一个程序更改设置,因此很脆弱。在具有不同时区用户的服务器上ZoneId.systemDefault() 根本无法工作。您需要从某个客户端/浏览器传递时区。有很多方法,您可以在设置中搜索方法。

    …但不想每次都保存 LocalDateTime 而是 UTC 一个。

    很好,建议使用 UTC。同样,执行此操作的方法取决于您的设置。如果保存到 SQL 数据库中,您可以保存 OffsetDateTimeInstant(前提是您使用的是符合 JDBC 4.2 的驱动程序,这很有可能)所以上面的代码可能就足够了。如果您需要将日期和时间存储为字符串,请使用Instant.toString() 生成 ISO 8601 格式的字符串。我建议不要使用LocalDateTime 作为UTC 日期和时间,因为它不“知道”自己是UTC,这使得出错的风险太大。其他例子:

        Instant utcInstant = localDateTime.atZone(userTimeZone).toInstant();
        System.out.println("utcInstant: " + utcInstant);
    
        String utcDateTimeString = utcDateTime.toString();
        System.out.println("utcDateTimeString: " + utcDateTimeString);
    
    utcInstant: 2019-12-24T23:00:00Z
    utcDateTimeString: 2019-12-24T23:00Z
    

    utcInstant 这个名字实际上要么是多余的要么是无意义的,因为一方面Instant 与时区无关,另一方面总是以 UTC 打印。我想不出一个更好的名字,对不起。 Anuway 如果可以的话,它可以存储在你的设置中。

    【讨论】:

    • 我做了一些研究,我明白为什么我不应该将 LocalDateTime 用于 UTC。但就我而言,我必须将其转换为 LocalDateTime。问题很明显,我无法计算正确的时间,因为它在转换后总是丢失。我认为最好的(为了将来的目的)是重构方法及其依赖项,将其存储为 Instant 或 OffsetDateTime 就像你说的那样。
    猜你喜欢
    • 2016-04-10
    • 1970-01-01
    • 2015-08-19
    • 2021-03-12
    • 2019-03-22
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多