SimpleDateFormat解析方法之谜
SimpleDateFormat parse method mystery
我知道 SimpleDateFormat.parse
依赖日历 API,它取决于本地 JVM 时区(计算机的)。假设 JVM 时区是 IST。
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
从输出来看,它似乎从 EST 转换为 IST(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
在这种情况下它保持时间不变。在这种情况下,我将时区设置为与 JVM 本地时区相同。
请帮助我理解 parse
方法的行为。不过,我很想知道这种行为背后的原因。
我知道 java.util.Date
和 java.text.SimpleDateFormat
遗留 类 现在已经过时了。
参考文献:
- Why SimpleDateFormat.format() and SimpleDateFormat.parse() are giving different time though setting only one TimeZone?
- How do I convert date/time from one timezone to another?
- https://www.codeproject.com/Tips/1190426/When-Parsing-Formatting-Dates-in-Java-Make-Sure-Yo
首先,Date
和 SimpleDateFormat
是遗留的 class 并且现在已过时,您是对的。所以我建议你不要使用它们,而是使用 java.time,现代的 Java 日期和时间 API。在许多优点中,它对时区之间的转换更加明确,我希望这能帮助您理解代码的作用。
其次,您做了许多不正确或至少不充分的事情:
- 不要将日期时间存储为字符串。始终将它们作为日期时间对象存储在 Java 中。当您这样做时,您永远不需要将日期时间字符串从一个区域转换为另一个区域。
Instant
(来自 java.time 的 class)是一个时间点,据我所知,您应该在此处使用。
- 不要依赖三个字母的时区缩写。其中很多是模棱两可的,包括 IST 和 EST,后者不是真正的时区,所以你在每年的这个时候得到的(当 America/New_York 时区使用 EDT 而不是 EST),我不知道。
- 重复一遍,使用现代 classes,而不是过时的。
出于好奇发生了什么事?
一个老式的Date
表示一个独立于时区的时间点(在内部它存储它的值作为自纪元以来的毫秒计数,但这是一个我们不需要知道的实现细节或关心自己)。
在您的第一个示例中,您的字符串被解析为对应于 16:28:25 UTC、印度 21:58:25、纽约 12:28:25 或 11:28:25 的时间点在牙买加。我提到牙买加是因为它是少数几个全年都使用东部标准时间 (EST) 的地方之一。大多数使用 EST 的地点仅在冬季使用,而不是每年的这个时候。当您在调试器中查看 Date
时,调试器会调用 Date
上的 toString
以获取要显示的字符串。 toString
依次使用 JVM 的时区来生成字符串。在你的情况下它是 Asia/Kolkata,这就是你得到 21:58:25.
的原因
在第二种情况下,相同的字符串被解析为对应于 05:58:25 UTC、印度 11:28:25、纽约 01:58:25 或 00:58:25 的时间点] 在牙买加。您的调试器再次调用 toString
,它再次使用您的 JVM 时区并转换回 11:28:25 IST。当您在同一时区解析和打印时,您会得到同一天的时间。
链接
- EST – Eastern Standard Time / Eastern Time (Standard Time)
- Oracle tutorial: Date Time 解释如何使用
java.time
.
- Time Zone Converter – Time Difference Calculator,在线,实用Asia/Kolkata,UTC,金斯敦(牙买加),纽约等时区转换。
我知道 SimpleDateFormat.parse
依赖日历 API,它取决于本地 JVM 时区(计算机的)。假设 JVM 时区是 IST。
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
从输出来看,它似乎从 EST 转换为 IST(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
在这种情况下它保持时间不变。在这种情况下,我将时区设置为与 JVM 本地时区相同。
请帮助我理解 parse
方法的行为。不过,我很想知道这种行为背后的原因。
我知道 java.util.Date
和 java.text.SimpleDateFormat
遗留 类 现在已经过时了。
参考文献:
- Why SimpleDateFormat.format() and SimpleDateFormat.parse() are giving different time though setting only one TimeZone?
- How do I convert date/time from one timezone to another?
- https://www.codeproject.com/Tips/1190426/When-Parsing-Formatting-Dates-in-Java-Make-Sure-Yo
首先,Date
和 SimpleDateFormat
是遗留的 class 并且现在已过时,您是对的。所以我建议你不要使用它们,而是使用 java.time,现代的 Java 日期和时间 API。在许多优点中,它对时区之间的转换更加明确,我希望这能帮助您理解代码的作用。
其次,您做了许多不正确或至少不充分的事情:
- 不要将日期时间存储为字符串。始终将它们作为日期时间对象存储在 Java 中。当您这样做时,您永远不需要将日期时间字符串从一个区域转换为另一个区域。
Instant
(来自 java.time 的 class)是一个时间点,据我所知,您应该在此处使用。 - 不要依赖三个字母的时区缩写。其中很多是模棱两可的,包括 IST 和 EST,后者不是真正的时区,所以你在每年的这个时候得到的(当 America/New_York 时区使用 EDT 而不是 EST),我不知道。
- 重复一遍,使用现代 classes,而不是过时的。
出于好奇发生了什么事?
一个老式的Date
表示一个独立于时区的时间点(在内部它存储它的值作为自纪元以来的毫秒计数,但这是一个我们不需要知道的实现细节或关心自己)。
在您的第一个示例中,您的字符串被解析为对应于 16:28:25 UTC、印度 21:58:25、纽约 12:28:25 或 11:28:25 的时间点在牙买加。我提到牙买加是因为它是少数几个全年都使用东部标准时间 (EST) 的地方之一。大多数使用 EST 的地点仅在冬季使用,而不是每年的这个时候。当您在调试器中查看 Date
时,调试器会调用 Date
上的 toString
以获取要显示的字符串。 toString
依次使用 JVM 的时区来生成字符串。在你的情况下它是 Asia/Kolkata,这就是你得到 21:58:25.
在第二种情况下,相同的字符串被解析为对应于 05:58:25 UTC、印度 11:28:25、纽约 01:58:25 或 00:58:25 的时间点] 在牙买加。您的调试器再次调用 toString
,它再次使用您的 JVM 时区并转换回 11:28:25 IST。当您在同一时区解析和打印时,您会得到同一天的时间。
链接
- EST – Eastern Standard Time / Eastern Time (Standard Time)
- Oracle tutorial: Date Time 解释如何使用
java.time
. - Time Zone Converter – Time Difference Calculator,在线,实用Asia/Kolkata,UTC,金斯敦(牙买加),纽约等时区转换。