设置 Java 中的日期时间zone

huangapple go评论76阅读模式
英文:

Set timeZone in Date Java

问题

尝试在 Date 中设置时区(我知道 Date 已被弃用)

LOG.error(modifiedDate + " 在服务中的日期"); //Mon Sep 21 06:15:00 CDT 2020
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z", Locale.ENGLISH);
format.setTimeZone(TimeZone.getDefault());
String dateString = format.format(modifiedDate);
LOG.error(dateString + " 日期字符串"); //2020-09-21 06:15:00 -0500
Date date = format.parse(dateString);
LOG.error(date + " 解析后的日期"); //Mon Sep 21 06:15:00 CDT

解析后时区没有改变,我漏掉了什么吗?

英文:

Trying to set the timeZone in Date( I know Date is deprecated)

	LOG.error(modifiedDate + "Date in service"); //Mon Sep 21 06:15:00 CDT 2020
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z", Locale.ENGLISH);
format.setTimeZone(TimeZone.getDefault());
String dateString = format.format(modifiedDate);
LOG.error(dateString + "  dateString"); //2020-09-21 06:15:00 -0500
Date date = format.parse(dateString);
LOG.error(date + "    date after parsing"); //Mon Sep 21 06:15:00 CDT 

timeZone isn't changing after the parse, what am I missing?

答案1

得分: 6

一个 java.util.Date 对象是在撒谎。它不是一个日期。它是一个时间点,并且没有时区信息。它只是一个围绕自纪元以来的毫秒数的包装器。它在物理上没有必要的字段来存储时区信息。

(让我们停止称 j.u.Date 的实例为“日期”,因为它实际上不是一个日期。这就好像你把所有的 Integer 实例都称为“字符串”,把所有的文件称为“外婆”,差不多荒谬)。我们应该用它们正确的名称来称呼它们:“糟糕的时刻”。

你所做的是__设置了格式化器对象的时区__。这正常运作:当你使用附带有时区信息的格式化器格式化这个_糟糕的时刻_对象时,你得到了被翻译成人类可读形式的“时间点”,带有时区信息,并根据该时区进行调整。

然后你要求将其解析回来,但这是个问题:那是一个非常广泛的工作;“将这堆字符解析为一个'糟糕的时刻'”。

在这种情况下,你提供的字符信息已经包含了时区信息,因此将会使用它。记住,Date 对象是糟糕的时刻 - 它们不包含时区信息!!

这应该会引起一些疑虑 - 作为最后的动作,你记录了 date,实际上这相当于在你的_糟糕的时刻_实例上调用 toString() 方法的结果。这将会... 创建一个使用系统默认时区的格式化器,并用它来以人类可读的形式呈现时间,但不要弄错了,实际上存储在你的_糟糕的时刻_对象中的并不是这个。那里面只存储了 1600686900000。就是这样。

我强烈建议你遵循 deHaar 的评论:不,你不想要_糟糕的时刻_。如果你手头有一个类型为_糟糕的时刻_(java.util.Date)的值,立即将其转换为 Instant

如果你必须将一个计算出的时间值传递回某个方法、接口、字段或其他地方,并且必须以日期形式表示,那么将你的_好时刻_实例(java.time.Instant)转换回_糟糕的时刻_形式。

英文:

A java.util.Date object is lying. It's not a date. It is a moment in time, and it has no timezone information. It's just a wrapper around millis-since-epoch. It physically doesn't have the neccessary fields to store that.

(let's stop calling an instance of j.u.Date a 'date', because it just isn't one. You might as well call all instances of Integer a 'string', and all files 'a Grandma', about as sane). Let's call them by their right name: "crappy instant".

What you've done is set the timezone of the formatter object. This is working as intended: When you format this crappy instant object with your formatter-with-timezone-info-attached, you get the 'instant in time', translated to human-consumable form, with timezone info, adjusted for that timezone.

Then you ask to parse it back in but that's an issue: that's a very broad job; 'parse this bunch of characters into a "crappy instant"'.

In this case, the bag o' chars you've given includes timezone info already so that will be used. Remember, Date objects are crappy instants - they contain no timezone!!

Which should then raise some eyebrows - as last act you log date, which effectively logs the result of invoking the toString() method on your crappy instant instance. This will.... create a formatter with the system default timezone and use that to render it in human form, but make no mistake, that is NOT actually what is stored in that crappy instant object you have. All that is stored in there is 1600686900000. That's it.

I strongly suggest you follow deHaar's comment: No, you don't want crappy instant. If you have a value handed to you of type crappy instant (java.util.Date), convert it to Instant immediately.

If you must hand off a calculated time value back to some method or interface or field or whatnot and must be in date form, convert your nice instant instance (java.time.Instant) back to a crappy instant form.

huangapple
  • 本文由 发表于 2020年9月22日 20:59:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/64010273.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定