无法在Android / Java中解析来自MongoDB的日期字符串

时间:2016-03-29 11:57:01

标签: java android mongodb date

我正在尝试解析来自MongoDB的日期(2015-06-25T00:00:00.000Z)。

try {
    DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH);
    Date date = format.parse("2015-06-25T00:00:00.000Z");
    return new Date().after(date);
    } catch (ParseException e) {
        e.printStackTrace();
    }
}

我哪里错了?

2 个答案:

答案 0 :(得分:8)

您的模式只接受第二个数字,但您的字符串也包含小数秒

yyyy-MM-dd'T'HH:mm:ss    'Z'
2015-06-25 T 00:00:00.000 Z

您需要使用

"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" 

答案 1 :(得分:2)

不要忽略Z

您的格式设置模式在Z周围有单引号。这意味着将“Z”解释为仅仅是文本,期待它然后忽略它。非常糟糕,因为Z有意义:祖鲁的缩写,意思是UTC time zone

通过忽略Z,解析将隐式应用JVM的当前默认时区。您的输入意味着UTC中一天的第一时刻(午夜时段),但在下面的代码中,您可以看到该值在我的默认区域America/Los_Angeles中误解为午夜 - 错误为7小时(我的区域当前offset from UTC)。

try {
    java.text.DateFormat format = new SimpleDateFormat ( "yyyy-MM-dd'T'HH:mm:ss'Z'" , Locale.ENGLISH );
    java.util.Date date = format.parse ( "2015-06-25T00:00:00Z" );
    System.out.println ( "date: " + date );
} catch ( ParseException e ) {
    e.printStackTrace ();
}

在此输出中,PDT表示太平洋时间的夏令时(DST)版本(更准确地命名为America/Los_Angeles)。请注意,时间是00:00:00,但错误 - 应该是前一天提前7小时,因为我的区域落后于 UTC。

  

日期:2015年6月25日星期五00:00:00

java.time

使用Java 8及更高版本中内置的java.time框架可以更轻松地完成这项工作。对于Java 6& 7,使用后端口ThreeTen-Backport。对于Android,改编后端口ThreeTenABP

在解析/生成日期时间值的文本表示时,默认情况下java.time类使用ISO 8601格式。您的输入恰好符合ISO 8601.因此无需指定格式化模式。

Instant是UTC时间轴上的一个时刻。

String input = "2015-06-25T00:00:00Z";
Instant instant = Instant.parse ( input );

如果需要,请申请proper time zone name

ZoneId zoneId = ZoneId.of ( "America/Los_Angeles" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );

转储到控制台。

System.out.println ( "input: " + input + " | instant: " + instant + " | zdt: " + zdt );
  

输入:2015-06-25T00:00:00Z |时刻:2015-06-25T00:00:00Z | zdt:2015-06-24T17:00-07:00 [America / Los_Angeles]

请注意,在此输出中,现在可以将相同的输入正确调整到America/Los_Angeles时区,方法是将七小时后移回上一个日期。

转换为/从java.time

避免使用java.util.Date。旧的日期时间类真的很糟糕。但是,如果需要,您可以在java.time类型和旧类型之间进行转换。在这种情况下,使用count-from - epoch毫秒。请注意,您可能会丢失一些数据,从java.util.Date中的纳秒分辨率到毫秒(不是在这种情况下,但可能在其他情况下)。

java.util.Date utilDate = new java.util.Date( instant.toEpochMilli() );