DateFormat.parse()给出错误的结果

时间:2017-10-28 20:49:52

标签: java date simpledateformat date-parsing

我已经玩了近6个小时了,看了看其他问题,但似乎无法弄清楚我做错了什么给了我这些奇怪的结果。这是我的代码

    String dateStr = "20171230";
    StringBuilder sb = new StringBuilder();
    sb.append(dateStr.subSequence(0, 4))
        .append("/")
        .append(dateStr.substring(4,6))
        .append("/")
        .append(dateStr.substring(6,8));

    dateStr = sb.toString();

    System.out.println("date string is " + dateStr);

    DateFormat df = new SimpleDateFormat("yyyy/mm/dd");

    df.setLenient(false);

    Date Date = null;

    try {
        Date = df.parse(dateStr);
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    System.out.println("Date is " + Date);

输出

date string is 2017/12/30
Date is Mon Jan 30 00:12:00 CST 2017

日期应该是12月30日,而不是1月30日。有人可以告诉我为什么会这样。

2 个答案:

答案 0 :(得分:1)

您传递一种简单日期格式的格式会在您认为月份的位置定义分钟。

注意时间输出如何设置为00:12。

相反,使用 YYYY / MM / DD

答案 1 :(得分:0)

请允许我提出一些建议,这些建议远远超出您的要求。我认为我的建议应该有所帮助。

首先,您不应该坚持使用已久的过时类DateSimpleDateFormatThe modern Java date and time API通常可以更好地使用,并且包含更少的令人不快的意外。它被称为JSR-310或java.time

其次,在从中提取日期之前,不需要使用StringBuilder重新格式化字符串。 20171230可以直接解析为日期。更糟糕的是,你转换字符串的方式,你没有验证长度:如果碰巧有9个数字而不是8个数字,你会想要捕获它并抛出异常,但你的代码只需要前8个数字,忽略是否​​还有更多。

最后,正如Trenton Trama已经在the other answer中指出的那样,格式模式字符串区分大小写。使用大写或小写字母是否以及在何处使用都很重要。使用不正确的情况很可能会导致错误的结果。这适用于过时的和现代的API。幸运的是,当涉及到解析时,现代API更倾向于在使用错误的情况时抛出异常,所以至少你被告知出了问题。

最后 - 最后,当您希望其他人像其他stackoverflowers一样阅读您的代码时,请使用编码约定来帮助我们。变量名以小写字母开头。当你有一个名为Date的类和一个名为Date的变量时,这一点尤其令人困惑。

以上总结为:

    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuuMMdd");
    String dateStr = "20171230";
    LocalDate date = LocalDate.parse(dateStr, dtf);
    System.out.println("Date is " + date);

输出是:

Date is 2017-12-30

问题:我可以在Java版本中使用现代API吗?

如果至少使用Java 6 ,则可以。