Java 时区转换
我知道 java Date 是无时区的,尝试在 Java Calendar 上设置不同的时区不会将日期转换为适当的时区。因此,我尝试了以下代码
public static String DATE_FORMAT="dd MMM yyyy hh:mm:ss";
public static String CURRENT_DATE_STRING ="31 October 2011 14:19:56 GMT";
DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(dateFormat.parseObject(CURRENT_DATE_STRING));
,但它输出错误的日期 Mon Oct 31 16:19:56
,而它必须是 12:19:56
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这里的主要问题是您的日期格式字符串使用 hh (12 小时制)而不是 HH (24 小时制)
其次,您的日期格式应指定您的日期字符串包含时区。
(或者,您可以取消注释行,以告诉它正确的时区)。
第三,您还应该使用 DateFormat 来输出屏幕时间...
最后,UTC = GMT,因此 UTC 时间也是 14:19:56
(GMT,“英国冬季时间”,与 UTC 相同,而BST 提前一小时)
输出:
31 Oct 2011 14:19:56 UTC
HTH
The main issue here is your date format string is using hh (12-hour clock) instead of HH (24-hour)
Secondly, your date format should specify that your date string contains the timezone.
(Alternatively you could uncomment the commented line, to tell it the correct timezone).
Thirdly, you should use a DateFormat to output the time to screen aswell...
Finally, UTC = GMT, so the UTC time is also 14:19:56
(GMT, 'British Winter Time', is the same as UTC, whereas BST is one hour ahead)
Output:
31 Oct 2011 14:19:56 UTC
HTH
tl;dr
在那一天,当时,在一些东欧时区,时钟比 UTC 早两个小时。因此,在
Europe/Helsinki
等地区,UTC (GMT) 的 14 点将显示为 16(而不是 12)。java.time
实际上,
java.util.Date
代表 UTC 中的一个时刻,即零小时-分钟-秒的偏移量。请注意
Date::toString
。这个可怕的toString
方法在生成文本时动态应用 JVM 当前的默认时区。这会产生该时区已成为该对象一部分的错觉。从不使用此类的众多原因之一。您应该使用现代的 java.time 类,而不是
Calendar
。具体来说,使用ZonedDateTime
来表示通过特定地区(时区)的人们使用的挂钟时间看到的时刻。您输入的
“31 October 2011 14:19:56 GMT”
与您的格式模式“dd MMM yyyy hh:mm:ss”
不匹配。该模式无法考虑您输入的偏移量,即末尾的GMT
指示的零小时-分钟-秒的偏移量。首先,不要使用此类格式交换日期时间值。学习使用 ISO 8601 标准格式来交换日期时间值作为文本。 java.time 类在解析/生成文本时默认方便地使用这些标准格式,因此根本不需要指定模式。
但是,如果您必须解析您的特定输入字符串,请定义一个格式模式来匹配。
请注意我们如何指定
Locale
来确定翻译输入时使用的人类语言和文化规范。显然您想以东欧时区的方式查看这一时刻。我会任意选择该地区的几个时区之一。
请注意,
EEST
不是实时时区。以大陆/地区
格式指定正确的时区名称 ,例如美国/蒙特利尔
、非洲/卡萨布兰卡
或太平洋/奥克兰
。切勿使用 2-4 个字母的缩写,例如EST
或IST
或EEST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。转储到控制台。
请注意小时如何从
14
更改为 < code>16 因为此时芬兰的时钟比 UTC 早两个小时。否,
14
是 UTC 时间。东欧领先 UTC,而不是落后。如上所示,芬兰当天的运行时间提前了两个小时,因此芬兰时钟上的小指针指向4
(16 小时)而不是12
。关于 java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧遗留日期时间类,例如
java.util.Date
,日历
, &SimpleDateFormat
。要了解更多信息,请参阅 Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范为 JSR 310。
Joda-Time 项目,现已在 维护模式,建议迁移到java.time< /a> 类。
您可以直接与数据库交换java.time对象。使用符合 JDBC 驱动程序 /jeps/170" rel="nofollow noreferrer">JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql.* 类。
从哪里获取 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time 。该项目是 java.time 未来可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如
间隔
,YearWeek
,YearQuarter
和 更多。tl;dr
On that date, at that time, in some eastern Europe time zones, the clocks were running two hours ahead of UTC. So the hour of 14 in UTC (GMT) will appear as 16 (not 12) in zones such as
Europe/Helsinki
.java.time
Actually, a
java.util.Date
represents a moment as seen in UTC, an offset of zero hours-minutes-seconds.Beware of
Date::toString
. That terribletoString
method dynamically applies the JVM’s current default time zone while generating its text. This creates an illusion of that time zone having been part of the object. One of many reasons to never use this class.You should be using the modern java.time classes, never
Calendar
. Specifically, useZonedDateTime
to represent a moment as seen through the wall-clock time used by the people of a particular region (a time zone).Your input of
"31 October 2011 14:19:56 GMT"
does not match your formatting pattern"dd MMM yyyy hh:mm:ss"
. That pattern fails to account for the offset of your input, an offset of zero hours-minutes-seconds indicated by theGMT
at the end.Firstly, do not exchange date-time values using such formats. Learn to use ISO 8601 standard formats for exchanging date-time values as text. The java.time classes conveniently use these standard formats by default when parsing/generating text, so no need to specify a pattern at all.
But if you must parse that particular input string of yours, define a formatting pattern to match.
Notice how we specified a
Locale
, to determine the human language and cultural norms used in translation of your input.Apparently you want to view this moment as seen in the time zone of eastern Europe. I will arbitrarily choose one of the several time zones in that area.
Be aware that
EEST
is not a real time zone. Specify a proper time zone name in the format ofContinent/Region
, such asAmerica/Montreal
,Africa/Casablanca
, orPacific/Auckland
. Never use the 2-4 letter abbreviation such asEST
orIST
orEEST
as they are not true time zones, not standardized, and not even unique(!).Dump to console.
Notice how the hour changed from
14
to16
because at that moment the clocks in Finland were running two hours ahead of UTC.No the hour
14
is in UTC. Eastern Europe runs ahead of UTC, not behind it. As seen above, Finland on that day was running two hours ahead, so the little hand on the clocks of Finland were pointing at4
(16 hour) rather than12
.About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as
java.util.Date
,Calendar
, &SimpleDateFormat
.To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for
java.sql.*
classes.Where to obtain the java.time classes?
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as
Interval
,YearWeek
,YearQuarter
, and more.使用乔达时间。它受到许多 StackOverflow 用户的推荐,并且有详细的时区转换示例记录。
祝你好运!
Use Joda Time. It's recommended by many StackOverflow users and is well documented with examples on timezone conversion.
Good luck!
整个输出是多少? Date.toString() 应该打印时区。也许您的情况不是 UTC。
What's the whole output? Date.toString() should print time zone. Maybe it's not in UTC in your case.