Java SimpleDateFormat 时间奇怪

Java SimpleDateFormat time wierdness

我正在尝试使用 java.text.SimpleDateFormat 将日期字符串解析为 java.util.Date;但是,生成的格式化日期是错误的。

这是一个显示问题的测试用例:

@Test
public void testSimpleDateFormat() throws Exception {
    String dateString = "2016-03-03 11:50:39.5960000";
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSS");
    Date date = format.parse(dateString);

    assertEquals(dateString, format.format(date));
}

这会导致以下失败:

org.junit.ComparisonFailure: 
Expected :2016-03-03 11:50:39.5960000
Actual   :2016-03-03 13:29:59.0000000

日期是正确的,但是时、分、秒、毫秒都错了。为什么 java.text.SimpleDateFormat 搞乱了我约会的时间?

您的模式表明 5960000 是毫秒数。这代表 5960 秒,所以大约 1 小时 39 分钟,这解释了您获得的日期与初始日期之间的差异。

java.time

您使用的旧版 类 已被证明令人困惑、麻烦且设计不佳。避开他们。它们已被 Java 8 及更高版本中内置的 java.time 框架所取代。

java.time 类 使用分辨率 nanoseconds, for up to nine digits of a decimal fraction of second. More than enough for your six digits (microseconds).

您输入的字符串接近标准 ISO 8601 格式。该格式在 java.time 中默认用于日期时间值的 parsing/generating 字符串表示。所以,需要指定解析模式。

将您的输入字符串转换为标准格式。将中间的 SPACE 替换为 T.

String input = "2016-03-03 11:50:39.5960000";
String inputStandardized = input.replace( " " , "T" );

将该字符串解析为日期时间对象。

LocalDateTime ldt = LocalDateTime.parse( inputStandardized );

要在时间轴上获取实际时刻,请为此输入分配一个偏移量或时区。

如果在 UTC 中,创建一个 OffsetDateTime

OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC );

如果需要特定时间,请创建一个 ZonedDateTime

ZonedDateTime zdt = ldt.atZone( ZoneId.of( "America/Montreal" ) ) ;

之前 Java 8

如果您还没有 Java 8 技术可用,请考虑添加 backport of java.time or Joda-Time (the inspiration for java.time). For Android, there is a specific wrapper of the backport, ThreeTenABP