SimpleDateFormat解析方法之谜

时间:2018-10-16 19:48:13

标签: java date datetime timezone simpledateformat

我知道i依赖于Calendar API,后者取决于本地JVM时区(计算机的时区)。假设JVM时区为IST。

SimpleDateFormat.parse

从输出看来,它已从EST转换为IST(JVM本地时区)。

SimpleDateFormat srcDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
srcDateFormat.setTimeZone(TimeZone.getTimeZone("EST"));
Date objDt = srcDateFormat.parse("2018-10-16 11:28:25"); //Time : 21:58:25 

在这种情况下,它使时间保持不变。在这种情况下,我将时区设置为与JVM本地时区相同。

请帮助我了解SimpleDateFormat srcDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); srcDateFormat.setTimeZone(TimeZone.getTimeZone("IST")); Date objDt = srcDateFormat.parse("2018-10-16 11:28:25"); //Time : 11:28:25 方法的行为。不过,我很好奇知道这种行为背后的原因。 我知道parsejava.util.Date旧类现在已过时。

参考文献:

1 个答案:

答案 0 :(得分:2)

首先,您正确的认为DateSimpleDateFormat是旧类,现在已经过时了。因此,我建议您不要使用它们,而应使用现代Java日期和时间API java.time。在许多优点中,关于时区之间的转换要更为明确,我希望它可以帮助您了解代码的作用。

第二,您做错了很多事情,或者至少做得不够充分:

  1. 不要将日期时间存储为字符串。始终将它们存储为Java中的日期时间对象。执行此操作时,您将不需要将日期时间字符串从一个区域转换为另一个区域。 Instant(来自java.time的一个类)是一个时间点,据我所知,应该在此处使用它。
  2. 请勿使用三个字母的时区缩写。它们中的很多都是模棱两可的,包括IST和EST,而后者不是真正的时区,所以您在每年的这个时候会得到什么(当America / New_York区域使用EDT而不是EST时),我不会不知道。
  3. 重复我自己,使用现代的类,而不是过时的类。

出于好奇,发生了什么事?

老式的Date代表一个时间点,与时区无关(内部存储其值,以自该纪元以来的毫秒数为单位,但这是我们无需了解或关注的实现细节)与)。

在第一个示例中,您的字符串被解析为一个时间点,该时间点对应于世界标准时间16:28:25,印度的21:58:25,纽约的12:28:25或牙买加的11:28:25 。我之所以说牙买加,是因为牙买加是全年碰巧使用东部标准时间(EST)的少数几个地方之一。大多数使用EST的地区都只在冬季使用,而不是每年的这个时候。当您在调试器中查看Date时,调试器会在toString上调用Date来显示一个字符串。 toString依次使用JVM的时区来生成字符串。在您的情况下是亚洲/加尔各答,这就是为什么您获得21:58:25的原因。

在第二种情况下,相同的字符串被解析为一个时间点,该时间点对应于UTC 05:58:25,印度11:28:25,纽约01:58:25或美国00:58:25牙买加调试器会再次调用toString,它会再次使用JVM的时区并将其转换回11:28:25 IST。在同一时区进行解析和打印时,您会获得一天中的同一时间。

链接