Java: почему конструктор Date устарел и что вместо него использовать?

java date deprecated

183193 просмотра

13 ответа

Я из мира C #, поэтому еще не слишком разбираюсь в Java. Eclipse сказал мне, что Dateэто устарело:

Person p = new Person();
p.setDateOfBirth(new Date(1985, 1, 1));

Почему? И что (особенно в случаях как выше) должно использоваться вместо этого?

Автор: Svish Источник Размещён: 12.11.2019 09:11

Ответы (13)


94 плюса

Решение

Конкретный Dateконструктор устарел и Calendarдолжен использоваться вместо него. Параметр JavaDocfor Date описывает, какие конструкторы устарели и как их заменить с помощью Calendar.

Автор: Ruben Размещён: 15.04.2011 01:27

236 плюса

java.util.DateКласс фактически не рекомендуется, так что конструктор, наряду с несколькими другими конструкторами / методы устарели. Это устарело, потому что такое использование плохо работает с интернационализацией. CalendarКласс следует использовать вместо этого:

Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 1988);
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DAY_OF_MONTH, 1);
Date dateRepresentation = cal.getTime();

Посмотрите на дату Javadoc:

http://download.oracle.com/javase/6/docs/api/java/util/Date.html

Автор: BuffaloBuffalo Размещён: 15.04.2011 01:30

67 плюса

ТЛ; др

LocalDate.of( 1985 , 1 , 1 )

…или же…

LocalDate.of( 1985 , Month.JANUARY , 1 )

подробности

В java.util.Date, java.util.Calendarи java.text.SimpleDateFormatклассы были доставлены слишком быстро , когда Java первого запуска и эволюционировал. Классы не были хорошо разработаны или реализованы. Попытки улучшения были предприняты, поэтому вы устали. К сожалению, попытки улучшения в основном не увенчались успехом. Вам следует вообще избегать этих занятий . Они вытесняются в Java 8 новыми классами.

Проблемы в вашем коде

У java.util.Date есть и дата, и часть времени. Вы проигнорировали часть времени в своем коде. Таким образом, класс Date будет принимать начало дня, как определено часовым поясом JVM по умолчанию, и применяет это время к объекту Date. Таким образом, результаты вашего кода будут различаться в зависимости от того, на каком компьютере он работает или какой часовой пояс установлен. Наверное, не то, что вы хотите.

Если вам нужна только дата, без временной части, например, для даты рождения, вы можете не использовать Dateобъект. Вы можете сохранить только строку даты в формате ISO 8601YYYY-MM-DD . Или используйте LocalDateобъект из Joda-Time (см. Ниже).

Joda времени

Первое, чему нужно научиться на Java: избегайте печально известных классов java.util.Date & java.util.Calendar в комплекте с Java.

Как правильно отмечено в ответе user3277382 , используйте либо Joda-Time, либо новый пакет java.time. * В Java 8.

Пример кода в Joda-Time 2.3

DateTimeZone timeZoneNorway = DateTimeZone.forID( "Europe/Oslo" );
DateTime birthDateTime_InNorway = new DateTime( 1985, 1, 1, 3, 2, 1, timeZoneNorway );

DateTimeZone timeZoneNewYork = DateTimeZone.forID( "America/New_York" );
DateTime birthDateTime_InNewYork = birthDateTime_InNorway.toDateTime( timeZoneNewYork ); 

DateTime birthDateTime_UtcGmt = birthDateTime_InNorway.toDateTime( DateTimeZone.UTC );

LocalDate birthDate = new LocalDate( 1985, 1, 1 );

Дамп на консоль…

System.out.println( "birthDateTime_InNorway: " + birthDateTime_InNorway );
System.out.println( "birthDateTime_InNewYork: " + birthDateTime_InNewYork );
System.out.println( "birthDateTime_UtcGmt: " + birthDateTime_UtcGmt );
System.out.println( "birthDate: " + birthDate );

Когда беги…

birthDateTime_InNorway: 1985-01-01T03:02:01.000+01:00
birthDateTime_InNewYork: 1984-12-31T21:02:01.000-05:00
birthDateTime_UtcGmt: 1985-01-01T02:02:01.000Z
birthDate: 1985-01-01

java.time

В этом случае код для java.time практически идентичен коду Joda-Time .

Мы получаем часовой пояс ( ZoneId) и создаем объект даты и времени, назначенный этому часовому поясу ( ZonedDateTime). Затем, используя шаблон « Неизменяемые объекты» , мы создаем новую дату-время, основываясь на том же моменте старого объекта (количество наносекунд с начала эпохи ), но назначенном другом часовом поясе. Наконец, мы получаем a, у LocalDateкоторого нет ни времени суток, ни часового пояса, хотя обратите внимание, что часовой пояс применяется при определении этой даты (например, новый день наступает раньше в Осло, чем в Нью-Йорке ).

ZoneId zoneId_Norway = ZoneId.of( "Europe/Oslo" );
ZonedDateTime zdt_Norway = ZonedDateTime.of( 1985 , 1 , 1 , 3 , 2 , 1 , 0 , zoneId_Norway );

ZoneId zoneId_NewYork = ZonedId.of( "America/New_York" );
ZonedDateTime zdt_NewYork = zdt_Norway.withZoneSameInstant( zoneId_NewYork );

ZonedDateTime zdt_Utc = zdt_Norway.withZoneSameInstant( ZoneOffset.UTC );  // Or, next line is similar.
Instant instant = zdt_Norway.toInstant();  // Instant is always in UTC.

LocalDate localDate_Norway = zdt_Norway.toLocalDate();

О java.time

Java.time каркас встроен в Java 8 и более поздних версий. Эти классы вытеснять неприятные старые устаревшие классы даты и времени , такие как java.util.Date, Calendar, и SimpleDateFormat.

Проект Joda-Time , находящийся сейчас в режиме обслуживания , рекомендует перейти на классы java.time .

Чтобы узнать больше, см. Учебник по Oracle . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .

Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии . Нет необходимости в строках, нет необходимости в java.sql.*классах.

Где взять классы java.time?

  • Java SE 8 , Java SE 9 , Java SE 10 и более поздние версии
    • Встроенный.
    • Часть стандартного Java API с комплексной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport .
  • Android
    • Более поздние версии Android связывают реализации классов java.time.
    • Для более ранних версий Android (<26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). Смотрите Как использовать ThreeTenABP… .

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь , такие как Interval, YearWeek, YearQuarter, и более .

Автор: Basil Bourque Размещён: 06.02.2014 09:12

11 плюса

Одна из причин, по которой конструктор устарел, заключается в том, что значение параметра year не соответствует ожидаемому. Javadoc говорит:

Начиная с версии 1.1 JDK, заменено на Calendar.set(year + 1900, month, date).

Обратите внимание, что поле year - это количество лет с тех пор 1900, поэтому ваш пример кода, скорее всего, не будет делать то, что вы ожидаете. И в этом все дело.

В общем, DateAPI поддерживает только современный западный календарь, имеет специфически определенные компоненты и ведет себя непоследовательно, если вы задаете поля.

CalendarИ GregorianCalendarинтерфейсы лучше Date, а третьи сторонние API , Joda времени , как правило , считается лучшим. В Java 8 они представили java.timeпакеты, и теперь они являются рекомендуемой альтернативой.

Автор: Stephen C Размещён: 15.04.2011 01:45

11 плюса

Я столкнулся с этим вопросом как с дубликатом нового вопроса, в котором был задан вопрос о том, каким должен быть недревесный способ получения Dateопределенного года, месяца и дня.

В приведенных здесь ответах сказано, что нужно использовать этот Calendarкласс, и это было правдой до выхода Java 8. Но в Java 8 стандартный способ сделать это:

LocalDate localDate = LocalDate.of(1985, 1, 1);

И тогда, если вам действительно это нужно java.util.Date, вы можете воспользоваться предложениями в этом вопросе .

Для получения дополнительной информации, ознакомьтесь с API или учебными пособиями по Java 8.

Автор: Kevin Workman Размещён: 28.05.2015 01:33

8 плюса

Обратите внимание, что Calendar.getTime()это недетерминированный в том смысле, что дневная часть по умолчанию принимает текущее время.

Для воспроизведения попробуйте выполнить следующий код пару раз:

Calendar c = Calendar.getInstance();
c.set(2010, 2, 7); // NB: 2 means March, not February!
System.err.println(c.getTime());

Выход например:

Sun Mar 07 10:46:21 CET 2010

Выполнение точно такого же кода через пару минут приводит к:

Sun Mar 07 10:57:51 CET 2010

Таким образом, в то время как set()вынуждает соответствующие поля корректировать значения, оно пропускает системное время для других полей. (Протестировано выше с Sun jdk6 и jdk7)

Автор: Tijn Porcelijn Размещён: 20.12.2013 10:03

6 плюса

Dateсамо по себе не устарело. Это просто много его методов. Смотрите здесь для деталей .

Используйте java.util.Calendarвместо этого.

Автор: Mike Thomsen Размещён: 15.04.2011 01:28

5 плюса

Большинство разработчиков Java в настоящее время используют сторонний пакет Joda-Time . Это широко признано, чтобы быть намного лучшей реализацией.

Однако в Java 8 будет новый пакет java.time. * . См. Эту статью, представляющую новый API даты и времени для JDK 8 .

Автор: davesbrain Размещён: 05.02.2014 10:49

1 плюс

Подобно тому, что предложил binnyb, вы можете рассмотреть возможность использования более нового метода Calendar> GregorianCalendar. Смотрите эти более свежие документы:

http://download.oracle.com/javase/6/docs/api/java/util/GregorianCalendar.html

Автор: Joshua Размещён: 15.04.2011 01:30

1 плюс

Вы можете создать метод, как new Date(year,month,date)в вашем коде, используя Calendarкласс.

private Date getDate(int year,int month,int date){
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.YEAR, year);
    cal.set(Calendar.MONTH, month-1);
    cal.set(Calendar.DAY_OF_MONTH, day);
    return cal.getTime();
}

Это будет работать так же, как устаревший конструктор Date

Автор: Sudhanshu Dubey Размещён: 11.07.2018 07:36

1 плюс

Поскольку конструктор Date устарел, вы можете попробовать этот код.

import java.util.Calendar;

  Calendar calendar = Calendar.getInstance();
     calendar.set(Calendar.HOUR_OF_DAY, 6);// for 6 hour
     calendar.set(Calendar.MINUTE, 0);// for 0 min
     calendar.set(Calendar.SECOND, 0);// for 0 sec
     calendar.set(1996,0,26);// for Date [year,month(0 to 11), date]

    Date date = new Date(calendar.getTimeInMillis());// calendar gives long value

    String mConvertedDate = date.toString();// Fri Jan 26 06:00:00 GMT+05:30 1996
Автор: Divyanshu Kumar Размещён: 24.09.2019 11:57

0 плюса

new GregorianCalendar(1985, Calendar.JANUARY, 1).getTime();

(путь до Java-8)

Автор: Curtis Yallop Размещён: 05.10.2018 06:57

0 плюса

Конструктор Date ожидает годы в формате лет, начиная с 1900 года, начиная с нуля, и устанавливает часы / минуты / секунды / миллисекунды в ноль.

Date result = new Date(year, month, day);

Таким образом, используя замену Календаря (годы с нулями, месяцы с нулями, дни с единицами) для устаревшего конструктора Date, нам нужно что-то вроде:

Calendar calendar = Calendar.getInstance();
calendar.clear(); // Sets hours/minutes/seconds/milliseconds to zero
calendar.set(year + 1900, month, day);
Date result = calendar.getTime();

Или используя Java 1.8 (в котором год начинается с нуля, а месяцы и дни равны единице):

Date result = Date.from(LocalDate.of(year + 1900, month + 1, day).atStartOfDay(ZoneId.systemDefault()).toInstant());

Вот равные версии Date, Calendar и Java 1.8:

int year = 1985; // 1985
int month = 1; // January
int day = 1; // 1st

// Original, 1900-based year, zero-based month, one-based day
Date date1 = new Date(year - 1900, month - 1, day);

// Calendar, zero-based year, zero-based month, one-based day
Calendar calendar = Calendar.getInstance();
calendar.clear(); // Sets hours/minutes/seconds/milliseconds to zero
calendar.set(year, month - 1, day);
Date date2 = calendar.getTime();

// Java-time back to Date, zero-based year, one-based month, one-based day
Date date3 = Date.from(LocalDate.of(year, month, day).atStartOfDay(ZoneId.systemDefault()).toInstant());

SimpleDateFormat format = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss.SSS");

// All 3 print "1985-Jan-01 00:00:00.000"
System.out.println(format.format(date1));
System.out.println(format.format(date2));
System.out.println(format.format(date3));
Автор: Joel Richard Koett Размещён: 03.05.2019 11:13
Вопросы из категории :
32x32