为什么我的打印日期错了?

时间:2014-01-29 12:15:42

标签: java android datetime

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

我读到的一些示例日期:

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

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

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

7 个答案:

答案 0 :(得分:5)

1月份Java为0;二月是1,依此类推。

请参阅Calendar.JANUARYCalendar.FEBRUARY

所以当你从文件中读到1时 你认为你读过JAN但你读过FEB。

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

答案 1 :(得分:2)

月份的索引是从0而不是1,因此10是11月,11是12月。

Calendar.MONTH

答案 2 :(得分:2)

来自文档:

  

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

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

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

答案 3 :(得分:2)

原因是计数从0开始。

January  == 0
February == 1 

等等。请参阅documentation

答案 4 :(得分:2)

问题在于你将9传递给了SimpleDateFormat,并且由于月份从0到11被索引,它将解析月份' 9'作为第10个月。

您需要从月中减去1:)

答案 5 :(得分:1)

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);

答案 6 :(得分:0)

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