gpt4 book ai didi

java - SimpleDateFormat setTimeZone 不工作

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:33:13 26 4
gpt4 key购买 nike

我正在使用下面的代码将时间转换为有效的 UTC

import java.text.SimpleDateFormat;
import static java.util.Calendar.*

def dt = "2018-03-19T06:00:00+01:00"
def format = "yyyy-MM-dd'T'HH:mm:ssX"

TimeZone tz = TimeZone.getDefault(); //getting up local time zone
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
SimpleDateFormat sdf = new SimpleDateFormat(format);
Date d = sdf.parse(dt);
TimeZone.setDefault(tz);

println d //output: 2018-03-19T05:00:00Z

println d.toTimestamp(); //Output: 2018-03-19 06:00:00.0

但是当我使用 TimeZone.setTimeZone(TimeZone.getTimeZone("UTC")); 时它就不起作用了。

它仅适用于 TimeZone.setDefault(TimeZone.getTimeZone("UTC"));

为什么会这样?

评论后更新:输出需要使用 CET,但使用 UTC

def dt = "2018-03-19T06:00:00+01:00"
def format = "yyyy-MM-dd'T'HH:mm:ssX"
SimpleDateFormat sdf = new SimpleDateFormat(format);
sdf.setTimeZone(TimeZone.getTimeZone("CET"))
Date d = sdf.parse(dt);

println d
println d.toTimestamp();

输出:

Mon Mar 19 05:00:00 UTC 2018
2018-03-19 05:00:00.0

最佳答案

java.time

    String dt = "2018-03-19T06:00:00+01:00";
OffsetDateTime dateTime = OffsetDateTime.parse(dt);
System.out.println(dateTime);

这打印

2018-03-19T06:00+01:00

与过时的 Date 类相反,java.time 中的 OffsetDateTime 是现代 Java 日期和时间 API,它确实包含 UTC抵消,顾名思义。我没有使用 Groovy 的经验,很抱歉不得不相信你能翻译我的 Java 代码。

如果你想确保得到一个特定的时区,而不管字符串中的偏移量是多少:

    ZoneId zone = ZoneId.of("Europe/Brussels");
ZonedDateTime dateTime = OffsetDateTime.parse(dt).atZoneSameInstant(zone);

这次的结果是:

2018-03-19T06:00+01:00[Europe/Brussels]

不要依赖像 CET 这样的三个字母的时区缩写。 CET 是许多欧洲时区的标准时间一半(没有夏令时/DST 的部分)的通用名称,这些时区通常共享时间,但并不总是这样做,并且在涉及历史日期时往往不同意时间。其他三个字母的缩写是模棱两可的,因此会导致更多的困惑。始终将时区指定为地区/城市,就像我对欧洲/布鲁塞尔所做的那样。当然,选择符合您所需时区的城市。

如果您认为您需要 java.sql.Timestamp — 您可能不需要它。如果使用 JDBC 4.2 或更高版本或类似的现代 JPA 实现,最好将 InstantLocalDateTime 存储到您的数据库中。选择取决于您的确切要求和数据库列的确切数据类型。

    Instant inst = dateTime.toInstant();
System.out.println(inst);

输出

2018-03-19T05:00:00Z

Instant 始终以 UTC 打印。如果没有足够新的 JDBC 驱动程序,您可以通过以下两种方式之一转换为 Timestamp:

    System.out.println(Timestamp.from(inst));
System.out.println(Timestamp.valueOf(dateTime.toLocalDateTime()));

2018-03-19 06:00:00.0
2018-03-19 06:00:00.0

因为我的时区与日期时间对象中的时区一致,所以我从两次转换中得到相同的结果。在其他时区,结果可能不同,您需要注意选择正确的结果。

你的代码出了什么问题?

当您使用 SimpleDateFormat 解析其中包含 UTC 偏移量的字符串时,它会使用该偏移量来确定时间点。在这种情况下,它不会使用您通过 setTimeZone 设置的时区。它不会将任何时区或偏移量放入它返回的 Date 中,因为 Date 不能包含时区。这只是一个时间点。

让很多人感到困惑的是 Date.toString() 的结果似乎包含时区缩写,如输出中的 UTC Mon Mar 19 05:00:00 UTC 2018toString() 使用 JVM 的时区设置来生成字符串。这就是 TimeZone.setDefault() 影响您获得的输出的原因:它设置 JVM 设置,影响在同一 JVM 中运行的所有程序。它不会影响 Date 对象本身,但只会影响其 toString() 的结果。

TimeZoneDateTimestamp 类早已过时。 SimpleDateFormat 也太麻烦了。我建议你根本不要使用这些类。 java.time 更易于使用。

链接

Oracle tutorial: Date Time解释如何使用 java.time

关于java - SimpleDateFormat setTimeZone 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49451976/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com