JodaTime从Java.util.Date转换为DateTime(或LocalDate)

时间:2012-01-30 19:11:57

标签: java jodatime java.util.date

当我构造DateTime(或LocalDate)时,我遇到了问题。我正在转换旧代码以在内部使用joda来使事情更加清晰。但是我遇到了+1900问题......

通过:

assertEquals(2082, new Date(2082, 1, 1).getYear());

这两个都失败了:

assertEquals(2083, new LocalDate(new Date(2083, 1, 1)).getYear());
assertEquals(2084, new DateTime(new Date(2084, 1, 1)).toLocalDateTime().getYear());

这里发生了什么?如何从Date对象获取DateTime?

3 个答案:

答案 0 :(得分:5)

来自java.util.Date(int year, int month, int date)的javadoc:

  

已过时。从JDK 1.1版开始,由Calendar.set(year +。)取代   1900年,月,日)或GregorianCalendar(年+ 1900,月,日)。

     

分配一个Date对象并初始化它以便它代表   午夜,当地时间,在指定日期的开始   年,月和日期参数。

     

参数:年份减去1900年。月份0-11之间。   在1-31之间的日期。

除了它声明years参数是1900年的偏移量之外,你不应该使用这个构造函数,因为它已被弃用。相反,请使用java.util.Calendar

Calendar cal = Calendar.getInstance();
cal.set(2083, 1, 1);
assertEquals(2083, new LocalDate(cal).getYear());

答案 1 :(得分:3)

你的代码很好。

您会得到令人困惑的结果,因为Date的构造函数及其getYear()方法适用于基于1900年的年份,这就是它们被弃用的原因。

另请注意,从DateLocalDate / LocalDateTime的转换需要一个时区,如果没有明确指定,则使用默认值。

答案 2 :(得分:1)

一些想法:

    Date date= new Date(2083, 1, 1);

    DateTime dt = new DateTime(2083, 1, 1, 0, 0, 0, 0); 

    assertEquals(2083, new LocalDate(dt).getYear());

    assertEquals(3983, new LocalDate(date).getYear());

确定。简短介绍:LocalDate是一个不可变的日期时间类,表示没有时区的日期。 (比较API,http://joda-time.sourceforge.net/apidocs/org/joda/time/LocalDate.html) LocalDate的计算使用年表进行。此年表将在内部设置为所有计算的UTC时区。 如果您查看DateTime对象(除了事实基本相同),它会根据时区计算其字段。使用与现代格里高利历相容的默认年表(ISOChronology)进行计算。

您的问题:java.util.Date构造函数使用年,月,日,年份为整数y - 1900。 在您的示例中,2083表示年份3983(!)(http://docs.oracle.com/javase/7/docs/api/java/util/Date.html)。 就是这样......你错过了-1900 ..是的,java.util.Date有一个1900问题;)

-Markus