Преобразование JodaTime из Java.util.Date в DateTime (или LocalDate)

У меня возникла проблема, когда я создаю 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());

Что тут происходит? Как получить DateTime из объекта Date?


person David M. Coe    schedule 30.01.2012    source источник
comment
Какие результаты вы получаете?   -  person Alexandre    schedule 30.01.2012
comment
Я получаю 3983 (это 2083 + 1900) и 3984 (это 2084 + 1900)   -  person David M. Coe    schedule 30.01.2012


Ответы (3)


Из javadoc для java.util.Date(int year, int month, int date):

Устарело. Начиная с JDK версии 1.1, заменен на Calendar.set(год + 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());
person Vlad    schedule 30.01.2012

Ваш код в порядке.

Вы получаете запутанные результаты, потому что конструктор Date и его метод getYear() работают с годами, основанными на 1900, поэтому они устарели.

Также обратите внимание, что преобразование из Date в LocalDate / LocalDateTime требует часового пояса и использует часовой пояс по умолчанию, если он не указан явно.

person axtavt    schedule 30.01.2012
comment
Разве DateTime не должен позаботиться об этом за меня? Или мне нужно построить объект даты со встроенным -1900? new Date(2082-1900, 1, 1) - person David M. Coe; 30.01.2012
comment
@DavidM.Coe: Какое ему дело? Date представляет точный момент времени, и JodaTime не может его изменить. И да, когда вы работаете с Date API, вам нужно заботиться о его особенностях. - person axtavt; 31.01.2012
comment
Вы можете представить себе случай, когда реализация DateTime(Date date) создаст объект DateTime, вычитающий -1900 из года. мне бы понравилось :( - person David M. Coe; 31.01.2012
comment
@DavidM.Coe: Но это также вычтет 1900 лет из текущей даты. - person axtavt; 31.01.2012

пара идей:

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

-Маркус

person Markus Eisele    schedule 30.01.2012