Java: почему конструктор Date устарел и что вместо него использовать?
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
должен использоваться вместо него. Параметр JavaDoc
for Date описывает, какие конструкторы устарели и как их заменить с помощью Calendar
.
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:3067 плюса
ТЛ; др
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
, и более .
11 плюса
Одна из причин, по которой конструктор устарел, заключается в том, что значение параметра year не соответствует ожидаемому. Javadoc говорит:
Начиная с версии 1.1 JDK, заменено на
Calendar.set(year + 1900, month, date)
.
Обратите внимание, что поле year - это количество лет с тех пор 1900
, поэтому ваш пример кода, скорее всего, не будет делать то, что вы ожидаете. И в этом все дело.
В общем, Date
API поддерживает только современный западный календарь, имеет специфически определенные компоненты и ведет себя непоследовательно, если вы задаете поля.
Calendar
И GregorianCalendar
интерфейсы лучше Date
, а третьи сторонние API , Joda времени , как правило , считается лучшим. В Java 8 они представили java.time
пакеты, и теперь они являются рекомендуемой альтернативой.
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:338 плюса
Обратите внимание, что 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)
6 плюса
Date
само по себе не устарело. Это просто много его методов. Смотрите здесь для деталей .
Используйте java.util.Calendar
вместо этого.
5 плюса
Большинство разработчиков Java в настоящее время используют сторонний пакет Joda-Time . Это широко признано, чтобы быть намного лучшей реализацией.
Однако в Java 8 будет новый пакет java.time. * . См. Эту статью, представляющую новый API даты и времени для JDK 8 .
Автор: davesbrain Размещён: 05.02.2014 10:491 плюс
Подобно тому, что предложил binnyb, вы можете рассмотреть возможность использования более нового метода Calendar> GregorianCalendar. Смотрите эти более свежие документы:
http://download.oracle.com/javase/6/docs/api/java/util/GregorianCalendar.html
Автор: Joshua Размещён: 15.04.2011 01:301 плюс
Вы можете создать метод, как 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
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:570 плюса
Конструктор 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
Вопросы из категории :
- java В чем разница между int и Integer в Java и C #?
- java Как я могу определить IP моего маршрутизатора / шлюза в Java?
- java Каков наилучший способ проверки XML-файла по сравнению с XSD-файлом?
- java Как округлить результат целочисленного деления?
- java Преобразование списка <Integer> в список <String>
- java Почему я не могу объявить статические методы в интерфейсе?
- date Как получить разницу между двумя датами в JavaScript?
- date Получить последний день месяца в Python
- date DateTime.Now против DateTime.UtcNow
- date Получить последнюю пятницу месяца в Java
- date Why does Javascript getYear() return 108?
- date Как вернуть только дату из типа данных SQL Server DateTime
- deprecated Лучшая практика помечать устаревший код в Ruby?
- deprecated getch устарела
- deprecated Как игнорировать предупреждения об устаревании в Python
- deprecated Почему класс Java Vector (и Stack) считается устаревшим или устаревшим?
- deprecated Почему тег <center> не рекомендуется в HTML?
- deprecated Конструктор Date (...) устарел. Что это значит? (Джава)