Объект Date для Calendar [Java]
У меня есть класс Movie
в нем у меня есть дата начала, продолжительность и дата остановки.
Начало и остановка Дата - это объекты даты (закрытые Дата startDate...)
(Это назначение, поэтому я не могу изменить это)
теперь я хочу автоматически вычислять stopDate, добавляя продолжительность (в мин) к startDate.
По моим сведениям, работа с временными манипуляциями с функциями Date является устаревшей, следовательно, неправильной практикой, но с другой стороны я не вижу способа конвертировать объект Date в объект календаря, чтобы манипулировать временем и переконвертировать его в объект Date,
Есть ли способ? И если есть наилучшая практика
Ответы
Ответ 1
Что вы можете сделать, это создать экземпляр GregorianCalendar
, а затем установить Date
как время запуска:
Date date;
Calendar myCal = new GregorianCalendar();
myCal.setTime(date);
Однако другой подход заключается в том, чтобы вообще не использовать Date
. Вы можете использовать такой подход:
private Calendar startTime;
private long duration;
private long startNanos; //Nano-second precision, could be less precise
...
this.startTime = Calendar.getInstance();
this.duration = 0;
this.startNanos = System.nanoTime();
public void setEndTime() {
this.duration = System.nanoTime() - this.startNanos;
}
public Calendar getStartTime() {
return this.startTime;
}
public long getDuration() {
return this.duration;
}
Таким образом, вы можете получить как время начала, так и время от начала до остановки. Точность, конечно, зависит от вас.
Ответ 2
Calendar tCalendar = Calendar.getInstance();
tCalendar.setTime(date);
date - объект java.util.Date. Вы можете использовать Calendar.getInstance(), чтобы получить экземпляр календаря (гораздо более эффективный).
Ответ 3
Calendar.setTime()
Часто полезно посмотреть на подпись и описание методов API, а не только на их имя:) - Даже в стандартном API Java имена иногда могут вводить в заблуждение.
Ответ 4
Вам не нужно конвертировать в Calendar
для этого, вы можете просто использовать getTime()
/setTime()
.
getTime()
: Возвращает количество миллисекунд с 1 января 1970 года, 00:00:00 GMT, представленное этим объектом Date.
setTime(long time)
: Устанавливает этот объект Date для представления момента времени, равного миллисекундам времени после 1 января 1970 г. 00:00:00 ВРЕМЯ ПО ГРИНВИЧУ. )
Время в секунду составляет 1000 миллисекунд и 60 секунд в минуту. Просто сделайте математику.
Date now = new Date();
Date oneMinuteInFuture = new Date(now.getTime() + 1000L * 60);
System.out.println(now);
System.out.println(oneMinuteInFuture);
Суффикс L
в 1000
означает, что это a long
литерал; эти вычисления обычно легко перетекают int
.
Ответ 5
TL;DR
Instant stop =
myUtilDateStart.toInstant()
.plus( Duration.ofMinutes( x ) )
;
java.time
Ответы правильны, особенно Ответ Borgwardt. Но эти ответы используют устаревшие классы устаревших.
Исходные классы времени, связанные с Java, были заменены классами java.time. Выполните свою бизнес-логику в типах java.time. Преобразование в старые типы только там, где необходимо для работы со старым кодом, еще не обновленным для обработки типов java.time.
Если ваш Calendar
на самом деле является GregorianCalendar
вы можете конвертировать в ZonedDateTime
. Найти новые методы, добавленные к старым классам, чтобы облегчить преобразование в/из типов java.time.
if( myUtilCalendar instanceof GregorianCalendar ) {
GregorianCalendar gregCal = (GregorianCalendar) myUtilCalendar; // Downcasting from the interface to the concrete class.
ZonedDateTime zdt = gregCal.toZonedDateTime(); // Create `ZonedDateTime` with same time zone info found in the `GregorianCalendar`
end if
Если ваш Calendar
не является Gregorian
, вызовите toInstant
, чтобы получить объект Instant
. Класс Instant
представляет момент на временной шкале в UTC с разрешением наносекунды.
Instant instant = myCal.toInstant();
Аналогично, если начать с объекта java.util.Date
, преобразуйтесь в Instant
. Класс Instant
представляет момент на временной шкале в UTC с разрешением наносекунды (до девяти (9) цифр десятичной дроби).
Instant instant = myUtilDate.toInstant();
Применить часовой пояс, чтобы получить ZonedDateTime
.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
Чтобы получить объект java.util.Date
, пройдите через Instant
.
java.util.Date utilDate = java.util.Date.from( zdt.toInstant() );
Подробнее о преобразовании устаревших типов даты и времени java.time и отличной диаграмме см. мой ответ в другой вопрос.
Duration
Представьте промежуток времени как объект Duration
. Ваш ввод в течение продолжительности - это количество минут, как указано в Вопросе.
Duration d = Duration.ofMinutes( yourMinutesGoHere );
Вы можете добавить это к началу, чтобы определить остановку.
Instant stop = startInstant.plus( d );
О java.time
Структура java.time встроена в Java 8 и более поздних версий. Эти классы вытесняют неприятный старый legacy классы даты-времени, такие как java.util.Date
, Calendar
и SimpleDateFormat
.
Проект Joda-Time, теперь в режим обслуживания, советует перейти на java.time.
Чтобы узнать больше, см. Учебник Oracle. И поиск Qaru для многих примеров и объяснений. Спецификация JSR 310.
Где получить классы java.time?
- Java SE 8 и SE 9 и позже
- Встроенный.
- Часть стандартного Java API с объединенной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и SE 7
- Большая часть функциональных возможностей java.time обратно переносится на Java 6 и 7 в ThreeTen-Backport.
- Android
Проект ThreeTen-Extra расширяет java.time с помощью дополнительных классов. Этот проект является доказательством возможных будущих дополнений к java.time. Здесь вы можете найти полезные классы, такие как Interval
, YearWeek
, YearQuarter
и больше.
Ответ 6
что-то вроде
movie.setStopDate(movie.getStartDate() + movie.getDurationInMinutes()* 60000);