0

我在构造 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?

4

3 回答 3

5

从 javadoc 为java.util.Date(int year, int month, int date)

已弃用。从 JDK 版本 1.1 开始,由 Calendar.set(year + 1900, month, date) 或 GregorianCalendar(year + 1900, month, date) 取代。

分配一个 Date 对象并对其进行初始化,使其表示本地时间午夜,在年、月和日期参数指定的一天的开始。

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

除了它声明 years 参数是从 1900 年偏移的事实之外,您不应该使用此构造函数,因为它已被弃用。相反,使用java.util.Calendar

Calendar cal = Calendar.getInstance();
cal.set(2083, 1, 1);
assertEquals(2083, new LocalDate(cal).getYear());
于 2012-01-30T19:40:04.243 回答
3

你的代码很好。

您会得到令人困惑的结果,因为 constructor ofDate及其getYear()方法适用于基于 1900 年的年份,这就是不推荐使用它们的原因。

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

于 2012-01-30T19:36:45.990 回答
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 问题;)

-马库斯

于 2012-01-30T19:44:07.503 回答