如何获取 OffsetDateTime->LocalDateTime 并将其保存为 UTC?
How to get OffsetDateTime->LocalDateTime and save this as UTC?
即使经过大量搜索,我也没有找到适合我的问题的答案。
它是 Java API 中的 DateConvertUtil class。
这是一项 refactoring/feature 任务。
我有一个方法,它解析给定的日期字符串,在另一个方法和 returns LocalDateTime 的帮助下格式化它(这有点必须 - 太多的依赖)。
我想获取用户的时区,转换(或可能不转换)为 LocalDateTime,但不想每次都保存 LocalDateTime,而是保存 UTC。
我现在的问题是如何解决这个问题。
我似乎没有得到 Offset。
解析器之前可以工作,但仅适用于 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 和时间戳的内容,但也许我只是想不通。
感谢任何帮助。
不是很清楚。您可能正在寻找以下内容:
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);
当我运行这个片段在我的时区(Europe/Copenhagen),输出是:
localDateTime: 2019-12-25T00:00
utcDateTime: 2019-12-24T23:00Z
你说:
I want to get the Timezone of the User, …
执行此操作的方法不同。在独立应用程序中,您可以像上面的代码一样尝试 ZonedId.systemDefault()
。它为您提供了 JVM 的默认时区,这可能与用户的意图一致,也可能不一致。并且可以随时从程序的另一部分或同一 JVM 中的另一个程序 运行ning 更改设置,因此很脆弱。在拥有不同时区用户的服务器上 ZoneId.systemDefault()
根本无法工作。您需要从某些 client/browser 传递时区。有很多方法,您可以在您的设置中搜索方法。
… BUT don't want to save the LocalDateTime but the UTC one everytime.
很好,建议使用 UTC。同样,执行此操作的方法取决于您的设置。如果保存到 SQL 数据库中,您可以保存 OffsetDateTime
或 Instant
(前提是您使用的是 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 如果你可以在你的设置中存储它是很好的。
即使经过大量搜索,我也没有找到适合我的问题的答案。 它是 Java API 中的 DateConvertUtil class。 这是一项 refactoring/feature 任务。
我有一个方法,它解析给定的日期字符串,在另一个方法和 returns LocalDateTime 的帮助下格式化它(这有点必须 - 太多的依赖)。
我想获取用户的时区,转换(或可能不转换)为 LocalDateTime,但不想每次都保存 LocalDateTime,而是保存 UTC。
我现在的问题是如何解决这个问题。 我似乎没有得到 Offset。
解析器之前可以工作,但仅适用于 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 和时间戳的内容,但也许我只是想不通。
感谢任何帮助。
不是很清楚。您可能正在寻找以下内容:
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);
当我运行这个片段在我的时区(Europe/Copenhagen),输出是:
localDateTime: 2019-12-25T00:00 utcDateTime: 2019-12-24T23:00Z
你说:
I want to get the Timezone of the User, …
执行此操作的方法不同。在独立应用程序中,您可以像上面的代码一样尝试 ZonedId.systemDefault()
。它为您提供了 JVM 的默认时区,这可能与用户的意图一致,也可能不一致。并且可以随时从程序的另一部分或同一 JVM 中的另一个程序 运行ning 更改设置,因此很脆弱。在拥有不同时区用户的服务器上 ZoneId.systemDefault()
根本无法工作。您需要从某些 client/browser 传递时区。有很多方法,您可以在您的设置中搜索方法。
… BUT don't want to save the LocalDateTime but the UTC one everytime.
很好,建议使用 UTC。同样,执行此操作的方法取决于您的设置。如果保存到 SQL 数据库中,您可以保存 OffsetDateTime
或 Instant
(前提是您使用的是 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 如果你可以在你的设置中存储它是很好的。