【问题标题】:Why is my printed date wrong?为什么我打印的日期有误?
【发布时间】:2014-02-21 05:49:54
【问题描述】:

我已经验证从文件中正确读取了日期,但是一旦我将SimpleDateFormat.format"dd/MM/yy" 模式一起使用,它突然增加了一个月。这使我相信宽松模式正在计算错误的值。但我不知道是什么让它增加了整整一个月。

我读到的一些示例日期:

16/09/2013
23/09/2013
30/09/2013
07/10/2013
14/10/2013
21/10/2013

用于解析日期的代码(它是我制作的日历的包装器):

public static SimpleDateTime parseDate(String date)
{
    String[] dateParts = date.split("[-\\.:/]");
    int day = Integer.parseInt(dateParts[0]);
    int month = Integer.parseInt(dateParts[1]);
    int year = Integer.parseInt(dateParts[2]);

    return new SimpleDateTime(dag, maand, jaar);
}

这里使用的构造函数:

public SimpleDateTime(int day, int month, int year)
{
    date = Calendar.getInstance();
    date.setLenient(true);
    setDay(day);
    setMonth(month);
    setYear(year);
}

日、月、年的设置器:

public void setYear(int year)
{
    date.set(Calendar.YEAR, year);
}

public void setMonth(int month)
{
    date.set(Calendar.MONTH, month);
}

public void setDay(int day)
{
    date.set(Calendar.DAY_OF_MONTH, day);
}

以及用于格式化日期的代码:

public String toString(String pattern)
{
    String output = new SimpleDateFormat(pattern, Locale.getDefault()).format(date.getTime());
    return output;
}

传递的模式在哪里:

"dd/MM/yy"

打算将日期打印为:

16/09/13
23/09/13

相反,我得到:

16/10/13
23/10/13

【问题讨论】:

    标签: java android datetime


    【解决方案1】:

    月份从 0 而非 1 开始编入索引,因此 10 是 11 月,11 是 12 月。

    Calendar.MONTH
    

    【讨论】:

      【解决方案2】:

      来自文档:

      get 和 set 的字段编号,表示月份。这是特定于日历的值。一年的第一个月是一月;最后一个取决于一年中的月数。

      因此,如果您检查 JANUARY,您会看到它从零开始。

      确保您的月份在 0-11 的区间内。可能在1-12。

      【讨论】:

        【解决方案3】:

        Java 中的一月是 0;二月是 1 日,以此类推。

        Calendar.JANUARYCalendar.FEBRUARY

        所以当你从文件中读取 1
        你以为你读的是一月,但你读的是二月。

        你应该这样做:date.set(Calendar.MONTH, month-1); 来解决这个问题。

        【讨论】:

        【解决方案4】:

        这是因为计数是从0开始的。

        January  == 0
        February == 1 
        

        等等。请参阅documentation

        【讨论】:

        • 我现在感觉很愚蠢,忽略了这一点。不过这有点令人困惑,因为其他字段不是从 0 开始的。
        【解决方案5】:

        问题是您将 9 传递给 SimpleDateFormat,并且由于月份的索引是从 0 到 11,它会将月份“9”解析为第 10 个月。

        你需要从月份中减去 1 :)

        【讨论】:

          【解决方案6】:

          Java 中的Calendar 类包含从0 开始的月份,因此当您将月份设置为0 时,它会将其视为JanuarySimpleDateFormat 提供了一种将值正确显示为01 的方法。

          Calendar cal = Calendar.getInstance();
          cal.set(Calendar.MONTH, 0);
          System.out.println(new SimpleDateFormat("dd/MM/yy").format(cal.getTime()));
          

          输出:

          29/01/14
          

          调整Calendar 可以使用的文件的解决方法(自 12 月起 - 或 12 将持续到 明年)或修改您的逻辑选择常量,例如:

          cal.set(Calendar.MONTH, Calendar.JANUARY);
          

          【讨论】:

            【解决方案7】:

            answer by peter.petrov 几乎是正确的,除了一个主要问题。就像您的问题一样,它忽略了时区

            供您参考,这种工作在 Joda-Time(或 Java 8 中的新 java.time.* 类)中要容易得多。 Joda-Time 干净得多,您甚至不会觉得需要创建包装类。

            // Specify the time zone for which the incoming date is intended.
            DateTimeZone timeZone = DateTimeZone.forID( "Europe/Brussels" );
            String input = "16/09/2013";
            
            DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yyyy").withZone( timeZone );
            DateTime dateTime = formatter.parseDateTime( input );
            String output = formatter.print( dateTime );
            

            转储到控制台…

            System.out.println( "dateTime: " + dateTime );
            System.out.println( "output: " + output );
            System.out.println( "millis since Unix epoch: " + dateTime.getMillis() );
            

            运行时……

            dateTime: 2013-09-16T00:00:00.000+02:00
            output: 16/09/2013
            millis since Unix epoch: 1379282400000
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-10-14
              • 1970-01-01
              • 2021-08-12
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多