java settimezone_java-SimpleDateFormat setTimeZone无法正常工作

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日期和时间API java.time中的OffsetDateTime确实包含一个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实现,最好将Instant或LocalDateTime存储到数据库中.选择取决于您的确切要求和数据库列的确切数据类型.

Instant inst = dateTime.toInstant();

System.out.println(inst);

输出量

2018-03-19T05:00:00Z

即时消息始终以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.toString()的结果似乎包含时区缩写,因为输出中的UTC是Mon Mar 19 05:00:00 UTC2018.发生的事情是toString()使用JVM的时区设置用于生成字符串.这就是TimeZone.setDefault()影响获得的输出的原因:它设置JVM设置,从而影响在同一JVM中运行的所有程序.它不会影响Date对象本身,但是只会影响其toString()的结果.

TimeZone,Date和Timestamp类早已过时. SimpleDateFormat也太麻烦了.我建议您完全不要使用这些类. java.time更好用.

链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值