Я использую java.util.Date
класс Java в Scala и хочу сравнить Date
объект и текущее время. Я знаю, что могу вычислить дельту с помощью getTime ():
(new java.util.Date()).getTime() - oldDate.getTime()
Тем не менее, это просто оставляет мне long
миллисекунды. Есть ли более простой и приятный способ получить дельту времени?
Date
,Calendar
иSimpleDateFormat
».java.time.Period
и / илиDuration
. Смотрите ответ Бэзила Бурка ниже .Ответы:
К
Date
сожалению, API JDK ужасно сломан. Я рекомендую использовать библиотеку Joda Time .У Joda Time есть понятие временного интервала :
РЕДАКТИРОВАТЬ: Между прочим, у Joda есть две концепции:
Interval
для представления интервала времени между двумя моментами времени (представляют время между 8:00 и 10:00), и a,Duration
который представляет промежуток времени без фактических временных границ (например, представляют два часа!)Если вас интересуют только сравнения времени, большинство
Date
реализаций (включая JDK) реализуетComparable
интерфейс, который позволяет вам использоватьComparable.compareTo()
источник
Comparable.compareTo()
, а неComparable.compare()
.java.time
пакет в Java 8 вдохновлен Joda-Time, но не является заменой. У каждого есть свои плюсы и минусы. К счастью, вам не нужно выбирать между ними. Используйте каждый для его сильных сторон, пока вы осторожны со своимиimport
заявлениями. Посмотрите этот другой ответ на примере java.time.Простой diff (без lib)
И тогда вы можете позвонить:
чтобы получить разницу в 2 даты в минутах.
TimeUnit
естьjava.util.concurrent.TimeUnit
, стандартный Java перечисление происходит от Nanos до нескольких дней.Удобный для восприятия diff (без lib)
http://ideone.com/5dXeu6
Вывод примерно такой
Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0}
, с заказанными единицами.Вам просто нужно преобразовать эту карту в удобную для пользователя строку.
Предупреждение
Приведенные выше фрагменты кода вычисляют простой diff между 2 моментами. Это может вызвать проблемы во время перехода на летнее время, как описано в этом посте . Это означает, что если вы вычислите разницу между датами без времени, у вас может отсутствовать день / час.
На мой взгляд, разница в датах является субъективной, особенно в дни. Ты можешь:
подсчитать количество прошедших 24 часов: день + 1 - день = 1 день = 24 часа
подсчитайте количество прошедшего времени, учитывая летнее время: день + 1 - день = 1 = 24 часа (но с использованием полуночи и летнего времени это может быть 0 дней и 23 часа)
посчитать число
day switches
, что означает день + 1 1 вечера - день 11 утра = 1 день, даже если прошедшее время составляет всего 2 часа (или 1 час, если есть переход на летнее время: p)Мой ответ действителен, если ваше определение различий по дням совпадает с первым случаем
С JodaTime
Если вы используете JodaTime, вы можете получить разность для 2-х дат (в миллисекундах с поддержкой ReadableInstant) дат:
Но вы также можете получить разницу для локальных дат / времени:
источник
Обратите внимание, что это работает с датами UTC, поэтому разница может быть выходной, если вы посмотрите на местные даты. А для правильной работы с местными датами требуется совершенно иной подход из-за перехода на летнее время.
источник
(endDate.getTime() - startDate.getTime())
к приведениюint
вместо конечного результата, и вы получаете целочисленное переполнение.Используя инфраструктуру java.time, встроенную в Java 8+:
Вывод:
Для получения дополнительной информации см. Руководство по Oracle и стандарт ISO 8601 .
источник
Period
вместоDuration
даты.Вы должны определить свою проблему более четко. Вы можете просто взять количество миллисекунд между двумя
Date
объектами и поделить на количество миллисекунд за 24 часа, например ... но:Date
всегда в UTCисточник
ТЛ; др
Преобразуйте ваши устаревшие
java.util.Date
объекты в их заменуjava.time.Instant
. Затем вычислите прошедшее время какDuration
.Формат ISO 8601:
PnYnMnDTnHnMnS
Разумный стандарт ISO 8601 определяет краткое текстовое представление промежутка времени в виде числа лет, месяцев, дней, часов и т. Д. Стандарт называет такой промежуток длительностью . Формат - это то,
PnYnMnDTnHnMnS
гдеP
означает «Период»,T
отделяет часть даты от части времени, а между ними находятся цифры, за которыми следует буква.Примеры:
P3Y6M4DT12H30M5S
три года, шесть месяцев, четыре дня, двенадцать часов, тридцать минут и пять секунд
PT4H30M
Четыре с половиной часа
java.time
Среда java.time, встроенная в Java 8 и более поздние, заменяет проблемные старые
java.util.Date
/java.util.Calendar
классы. Новые классы вдохновлены очень успешной платформой Joda-Time , задуманной как ее преемник, похожей по концепции, но реструктурированной. Определено JSR 310 . Продлевался ThreeTen-Extra проекта. Смотрите учебник .момент
Instant
Класс представляет собой момент на временной шкале в формате UTC с разрешением наносекунд (до девяти (9) цифр десятичной дроби).Лучше всего избегать устаревших классов, таких как
Date
/Calendar
. Но если вам нужно взаимодействовать со старым кодом, который еще не обновлен до java.time , конвертируйте туда и обратно. Вызовите новые методы преобразования, добавленные к старым классам. Для перехода отjava.util.Date
кInstant
, позвонитеDate::toInstant
.Промежуток времени
Классы java.time разделили эту идею представления промежутка времени в виде количества лет, месяцев, дней, часов, минут, секунд на две половины:
Period
годами, месяцами, днямиDuration
за дни, часы, минуты, секундыВот пример.
Дамп на консоль.
Оба
Period
иDuration
используют стандарт ISO 8601 для генерации строкового представления их значения.Java 9 добавляет методы для
Duration
получения части дней, часов, минут и секунд.Вы можете получить общее количество дней, часов, минут, секунд, миллисекунд или наносекунд за всю продолжительность.
В Java 9
Duration
класс получает новые методы для возврата различных частей дней, часов, минут, секунд, миллисекунд / наносекунд. Назовитеto…Part
методы:toDaysPart()
,toHoursPart()
и так далее.ChronoUnit
Если вы заботитесь только о более простой детализации времени, такой как «количество прошедших дней», используйте
ChronoUnit
перечисление.Другой пример.
О java.time
Java.time каркас встроен в Java 8 и более поздних версий. Эти классы вытеснять неприятные старые устаревшие классы даты и времени , такие как
java.util.Date
,Calendar
, иSimpleDateFormat
.Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на java.time.
Чтобы узнать больше, смотрите Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .
Где взять классы java.time?
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь , такие как
Interval
,YearWeek
,YearQuarter
, и более .Joda времени
ОБНОВЛЕНИЕ: проект Joda-Time сейчас находится в режиме обслуживания , и команда рекомендует переход на java.time. классы . Я оставляю этот раздел нетронутым для истории.
Библиотека Joda-Time использует ISO 8601 по умолчанию. Его
Period
класс анализирует и генерирует эти строки PnYnMnDTnHnMnS.Оказывает:
источник
Period
,Duration
иChronoUnit
, три класса , цель которых состоит в определении дельты между точками времени. Пожалуйста, укажите, какие части моей «стены текста» не имеют значения. И вы не правы, говоря, что Вопрос задал «дельту между датами»: Вопрос задал дельту междуDate
объектами, которые являются моментами даты и времени, а не «датами», несмотря на неудачное именование этого класса.java.util.Date
вInstant
(просто вызов.toInstant
). И я добавилMoment
раздел, чтобы объяснить. Вы упомянули паруDate
объектов, но на самом деле Вопрос использует только один существующийDate
объект, а затем фиксирует текущий момент, поэтому я сделал то же самое. Спасибо за ответ! Совет: откажитесь от использованияDate
- эти классы действительно ужасно ужасны.https://www.joda.org/joda-time/faq.html#datediff
источник
Немного более простая альтернатива:
Что касается «приятнее»: ну что именно вам нужно? Проблема представления временных интервалов в виде количества часов, дней и т. Д. Состоит в том, что это может привести к неточностям и неправильным ожиданиям из-за сложности дат (например, дни могут иметь 23 или 25 часов из-за перехода на летнее время).
источник
Использование миллисекундного подхода может вызвать проблемы в некоторых локалях.
Возьмем, к примеру, разницу между двумя датами 24.03.2007 и 25.03.2007 должна быть 1 день;
Однако, используя миллисекундный маршрут, вы получите 0 дней, если вы запустите его в Великобритании!
Лучший способ реализовать это - использовать java.util.Calendar
источник
Есть много способов найти разницу между датами и временем. Один из самых простых способов, о которых я знаю, был бы:
Заявление о печати является лишь примером - вы можете отформатировать его так, как вам нравится.
источник
Поскольку все ответы здесь верны, но используют устаревшие java или сторонние библиотеки, такие как joda или аналогичные, я просто оставлю другой путь, используя новые классы java.time в Java 8 и более поздних версиях. Смотрите Oracle Tutorial .
Используйте
LocalDate
иChronoUnit
:источник
Вычитание дат в миллисекундах работает (как описано в другом посте), но вы должны использовать HOUR_OF_DAY, а не HOUR при очистке временных частей ваших дат:
источник
Если вы не хотите использовать JodaTime или аналогичный, лучшее решение, вероятно, это:
Количество мс в день не всегда одинаково (из-за летнего времени и високосных секунд), но оно очень близко, и, по крайней мере, отклонения из-за перехода на летнее время отменяются в течение более длительных периодов. Поэтому деление, а затем округление дадут правильный результат (по крайней мере до тех пор, пока используемый локальный календарь не содержит странных скачков времени, кроме DST и високосных секунд).
Обратите внимание, что это все еще предполагает, что
date1
иdate2
установлено в то же время суток. Для разного времени дня сначала нужно определить, что означает «разница в дате», как указал Джон Скит.источник
date1.getTime()
противdate2.getTime()
. Таким образом, разность с 2016-03-03 по 2016-03-31 будет составлять 27 дней, а вам потребуется 28 дней.Math.round()
, который кажется безопасным в календарях «реального мира». Извините за шум.Взгляните на Joda Time , который представляет собой улучшенный API Date / Time для Java и должен отлично работать со Scala.
источник
Позвольте мне показать разницу между Joda Interval и Days:
источник
Если вам нужна отформатированная возвращаемая строка типа «2 дня 03h 42m 07s», попробуйте это:
источник
std
выше не определено.Примечание: startDate и endDates -> java.util.Date
и дата окончания
Как и в дни, вы также можете получить часы, минуты и секунды
источник
Посмотрите пример здесь http://www.roseindia.net/java/beginners/DateDifferent.shtml Этот пример показывает разницу в днях, часах, минутах, секундах и миллисекундах :).
источник
Используйте часовой пояс GMT, чтобы получить экземпляр Календаря, установите время, используя метод set класса Calendar. Часовой пояс GMT имеет смещение 0 (не очень важно) и флаг летнего времени, установленный на false.
источник
java.util.Date
и т. Д. Использование хака для установки часового пояса в GMT делает код нечувствительным к эффектам перехода на летнее время.Следующий код может дать вам желаемый результат:
источник
источник
источник
Date
, поэтому это сравнение является лучшим, что может быть достигнуто с учетом обстоятельств.Лучше всего сделать
Это число - количество миллисекунд в дне.
Одна дата другая дата дает вам разницу в миллисекундах.
Соберите ответ в двойной переменной.
источник
Вот правильное решение Java 7 в O (1) без каких-либо зависимостей.
источник
Это, вероятно, самый простой способ сделать это - возможно, потому, что я уже некоторое время кодирую на Java (с его по общему признанию неуклюжими библиотеками даты и времени), но этот код выглядит «простым и приятным» для меня!
Довольны ли вы результатом, возвращаемым в миллисекундах, или частью вашего вопроса является то, что вы бы предпочли, чтобы он был возвращен в каком-то альтернативном формате?
источник
Не используя стандартный API, нет. Вы можете свернуть свой собственный, выполнив что-то вроде этого:
Или вы можете использовать Joda :
источник
Просто чтобы ответить на первоначальный вопрос:
Поместите следующий код в функцию типа Long getAge () {}
Наиболее важным здесь является работа с длинными числами при умножении и делении. И, конечно, смещение, которое Java применяет в исчислении дат.
:)
источник
Поскольку вопрос помечен с помощью Scala,
источник
После прохождения всех остальных ответов, чтобы сохранить тип даты Java 7, но быть более точным / стандартным с подходом Java 8 diff,
источник
попробуй это:
Вы можете редактировать строку в параметре parse () param.
источник