Я хотел бы иметь метод CompareTo, который игнорирует часть времени java.util.Date. Я думаю, что есть несколько способов решить эту проблему. Какой самый простой способ?
Обновление: хотя в то время Joda Time была хорошей рекомендацией, по возможности используйте java.time
библиотеку из Java 8+.
Я предпочитаю использовать Joda Time, что делает это невероятно простым:
DateTime first = ...;
DateTime second = ...;
LocalDate firstDate = first.toLocalDate();
LocalDate secondDate = second.toLocalDate();
return firstDate.compareTo(secondDate);
РЕДАКТИРОВАТЬ: Как отмечено в комментариях, если вы используете, DateTimeComparator.getDateOnlyInstance()
это еще проще :)
// TODO: consider extracting the comparator to a field.
return DateTimeComparator.getDateOnlyInstance().compare(first, second);
(«Используйте Joda Time» - это основа почти всех вопросов SO, которые задают java.util.Date
или java.util.Calendar
. Это совершенно превосходный API. Если вы делаете что- то существенное с датами / временем, вы должны действительно использовать его, если возможно).
Если вы абсолютно вынуждены использовать встроенный API, вы должны создать экземпляр Calendar
с соответствующей датой и с использованием соответствующего часового пояса. Затем вы можете установить для каждого поля в каждом календаре значение часа, минуты, секунды и миллисекунды, равное 0, и сравнить полученное время. Определенно неприглядный по сравнению с решением Joda, хотя :)
Часовой пояс часть важна: java.util.Date
это всегда основан на UTC. В большинстве случаев, когда меня интересовала дата, это была дата в определенном часовом поясе . Это Calendar
само по себе заставит вас использовать Joda Time (если вы сами не хотите учитывать часовой пояс, что я не рекомендую).
Краткий справочник для разработчиков Android
//Add joda library dependency to your build.gradle file
dependencies {
...
implementation 'joda-time:joda-time:2.9.9'
}
Пример кода (пример)
DateTimeComparator dateTimeComparator = DateTimeComparator.getDateOnlyInstance();
Date myDateOne = ...;
Date myDateTwo = ...;
int retVal = dateTimeComparator.compare(myDateOne, myDateTwo);
if(retVal == 0)
//both dates are equal
else if(retVal < 0)
//myDateOne is before myDateTwo
else if(retVal > 0)
//myDateOne is after myDateTwo
Apache commons-lang почти вездесущ. Так что по этому поводу?
источник
Если вы действительно хотите использовать java.util.Date, вы должны сделать что-то вроде этого:
или, используя вместо этого Календарь (предпочтительно, так как getYear () и тому подобное устарели)
источник
Мое предпочтение было бы использовать Joda библиотеки insetad из
java.util.Date
непосредственно, как Joda делает различие между датой и временем (см YearMonthDay и DateTime классы).Однако, если вы хотите использовать,
java.util.Date
я бы предложил написать вспомогательный метод; напримеристочник
Есть мнения по поводу этой альтернативы?
источник
==
Оператор не обязательно возвращатьtrue
равноценные строки (использованиеequals()
). Вы также не можете использовать другие операторы сравнения, которые вы упомянули.sdf.format(date1).compareTo(sdf.format(date2));
.Если вы хотите сравнить только месяц, день и год двух дат, у меня работает следующий код:
Спасибо, Роб.
источник
Я тоже предпочитаю Joda Time , но вот альтернатива:
РЕДАКТИРОВАТЬ
Я добавлю UTC ниже, если вам нужно сравнить даты для определенного часового пояса, отличного от UTC. Если у вас есть такая необходимость, тогда я действительно советую идти за Йодой.
источник
Math.abs(second.getTime() - first.getTime()) < 1000L*60*60*24
< oneDay
.ТЛ; др
Избегайте устаревших классов даты и времени
Избегайте проблемных старых унаследованных классов даты и времени, таких как
Date
&Calendar
, теперь замененных классами java.time.Использование java.time
A
java.util.Date
представляет момент на временной шкале в UTC. Эквивалент в java.time естьInstant
. Вы можете конвертировать, используя новые методы, добавленные в унаследованный класс.Вы хотите сравнить по дате. Часовой пояс имеет решающее значение при определении даты. В любой момент времени дата меняется по всему земному шару в зависимости от зоны. Например, через несколько минут после полуночи в Париже Франция - новый день, а в Монреале-Квебеке все еще «вчера» .
Укажите правильное время имя зоны в формате
continent/region
, напримерAmerica/Montreal
,Africa/Casablanca
илиPacific/Auckland
. Никогда не используйте 3-4-буквенное сокращение, такое какEST
или,IST
поскольку они не являются истинными часовыми поясами, не стандартизированы и даже не уникальны (!).Применить
ZoneId
к,Instant
чтобы получитьZonedDateTime
.LocalDate
Класс представляет собой дату только значение без времени суток и без временной зоны. Мы можем извлечьLocalDate
изZonedDateTime
, эффективно устраняя часть времени суток.Теперь сравните, используя методы , такие как
isEqual
,isBefore
, иisAfter
.Смотрите этот код в прямом эфире на IdeOne.com .
О 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
, и более .источник
Уже упоминавшиеся apache commons-utils :
дает вам объект Date, содержащий только дату, без времени, и вы можете сравнить его с
Date.compareTo
источник
Боюсь, что не существует метода сравнения двух дат, который можно было бы назвать «простым» или «простым».
При сравнении двух экземпляров времени с любым видом пониженной точности (например, просто сравнение дат) вы всегда должны учитывать, как часовой пояс влияет на сравнение.
Если
date1
это указание события , которое произошло в +2 часового пояса иdate2
уточняет событие , которое произошло в EST, к примеру, вы должны позаботиться , чтобы правильно понять последствие сравнения.Ваша цель - выяснить, произошли ли два события в одну и ту же календарную дату в соответствующих часовых поясах? Или Вам нужно знать, попадают ли две даты в одну и ту же календарную дату в определенном часовом поясе (например, UTC или местный TZ).
Как только вы выясните, что именно вы пытаетесь сравнить, это просто вопрос получения тройки год-дата-дата в соответствующем часовом поясе и проведите сравнение.
Время Joda может заставить реальную операцию сравнения выглядеть намного чище, но семантика сравнения все еще является чем-то, что вам нужно выяснить самостоятельно.
источник
Если вы используете Java 8, вы должны использовать
java.time.*
классы для сравнения дат - предпочтительнее различныхjava.util.*
классовнапример; https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html
источник
Если вы просто хотите сравнить только две даты без времени, то вам может помочь следующий код:
источник
Вот решение от этого блога: http://brigitzblog.blogspot.com/2011/10/java-compare-dates.html
т.е. вы можете видеть, меньше ли разница во времени в миллисекундах, чем продолжительность одного дня.
источник
`
`
источник
Я не знаю, что это новое, или иначе, но я покажу вам, как я сделал
источник
Просто проверьте DAY_OF_YEAR в сочетании со свойством YEAR
РЕДАКТИРОВАТЬ:
Теперь мы можем использовать возможности функций расширения Kotlin
источник
В Java 8 вы можете использовать LocalDate, который очень похож на один из Joda Time.
источник
Это поможет вам сравнить даты без учета времени.
источник
Используя getDateInstance SimpleDateFormat, мы можем сравнивать только два объекта даты без времени. Выполните приведенный ниже код.
источник
Использование http://mvnrepository.com/artifact/commons-lang/commons-lang
источник
DateUtils.isSameDay(date1, date2)
.Другой простой метод сравнения, основанный на ответах здесь и моих наставнических указаниях
РЕДАКТИРОВАТЬ : Согласно @Jonathan Drapeau, приведенный выше код не удается в некоторых случаях (я хотел бы видеть эти случаи, пожалуйста), и он предложил следующее, как я понимаю:
Обратите внимание, что класс Date устарел, поскольку он не поддается интернационализации. Класс Календарь используется вместо!
источник
getXxx
методыDate
.Во-первых, имейте в виду, что эта операция зависит от часового пояса. Так что выберите, хотите ли вы сделать это в UTC, в часовом поясе компьютера, в своем любимом часовом поясе или где. Если вы еще не уверены, что это важно, посмотрите мой пример внизу этого ответа.
Поскольку ваш вопрос не совсем ясен по этому поводу, я предполагаю, что у вас есть класс с полем экземпляра, представляющим момент времени и реализующий его
Comparable
, и вы хотите, чтобы естественный порядок ваших объектов был по дате, но не по времени из этого поля. Например:java.time
Классы Java 8Я взял на себя свободу изменять тип поля вашего экземпляра с
Date
наInstant
, соответствующий класс в Java 8. Я обещаю вернуться к рассмотрениюDate
ниже. Я также добавил постоянную часового пояса. Вы можете установить егоZoneOffset.UTC
илиZoneId.of("Europe/Stockholm")
или, что вы считаете подходящим (установка его наZoneOffset
произведения, потому чтоZoneOffset
это подклассZoneId
).Я решил показать решение с использованием классов Java 8. Вы просили самый простой способ, верно? :-) Вот
compareTo
метод, который вы просили:Если вам не нужно время часть
when
, это, конечно , проще объявить и пропустить все преобразования. Тогда нам больше не нужно беспокоиться о часовом поясе.when
LocalDate
Теперь предположим, что по какой-то причине вы не можете объявить свое
when
полеInstant
или вы хотите оставить его старомоднымDate
. Если вы все еще можете использовать Java 8, просто преобразуйте его вInstant
, а затем сделайте как раньше:Аналогично для
o.when
.Нет Java 8?
Если вы не можете использовать Java 8, есть два варианта:
Calendar
илиSimpleDateFormat
.Старомодные способы
Ответ Адамски показывает вам, как избавиться от части времени,
Date
используяCalendar
класс. Я предлагаю вам использовать,getInstance(TimeZone)
чтобы получитьCalendar
экземпляр для часового пояса, который вы хотите. В качестве альтернативы вы можете использовать идею из второй половины ответа Йорна .Использование
SimpleDateFormat
действительно косвенный способ использования,Calendar
поскольку объектSimpleDateFormat
содержитCalendar
объект. Тем не менее, вы можете найти это менее хлопотно, чем использоватьCalendar
напрямую:Это было вдохновлено ответом Роба .
Зависимость от часового пояса
Почему мы должны выбрать определенный часовой пояс? Скажем, мы хотим сравнить два раза в UTC: 24 марта, 0:00 (полночь) и 12:00 (полдень). Если вы сделаете это в CET (скажем, в Европе / Париже), это будет 1 час ночи и 1 час дня 24 марта, то есть в тот же день. В Нью-Йорке (восточное дневное время) они наступают в 20:00 23 марта и в 8:00 24 марта, то есть не в одну и ту же дату. Так что важно, какой часовой пояс вы выберете. Если вы просто полагаетесь на настройки компьютера по умолчанию, вас могут ожидать сюрпризы, когда кто-то пытается запустить ваш код на компьютере в другом месте в этом глобализированном мире.
Ссылка на сайт
Ссылка на ThreeTen Backport, бэкпорт классов даты и времени Java 8 для Java 6 и 7: http://www.threeten.org/threetenbp/ .
источник
Мое предложение:
источник
Используя Apache Commons, вы можете сделать:
источник
это самый простой способ решить эту проблему.
источник
Я решил это путем сравнения по метке времени:
Я избегаю использовать Joda Time, потому что на Android используется огромное пространство. Размер имеет значение. ;)
источник
Другое решение, использующее Java 8 и Instant, использует метод truncatedTo
Пример:
источник
источник
Вот что сработало для меня:
источник
Как насчет того
DateUtil.daysBetween()
. Это Java, и она возвращает число (разница в днях).источник