Joda времени
Что касается добавления зависимости, я боюсь, что java.util.Date & .Calendar действительно настолько плохи, что первое, что я делаю в любом новом проекте, это добавляю библиотеку Joda-Time. В Java 8 вы можете использовать новый пакет java.time, вдохновленный Joda-Time.
Ядро Joda-Time - это DateTime
класс. В отличие от java.util.Date, он понимает свой назначенный часовой пояс ( DateTimeZone
). При конвертации из juDate назначьте зону.
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTimeQuébec = new DateTime( date , zone );
LocalDate
Один из способов проверить, попадают ли две даты-даты в одну и ту же дату, - преобразовать в LocalDate
объекты.
Это преобразование зависит от назначенного часового пояса. Чтобы сравнить LocalDate
объекты, они должны быть преобразованы в одной зоне.
Вот небольшой вспомогательный метод.
static public Boolean sameDate ( DateTime dt1 , DateTime dt2 )
{
LocalDate ld1 = new LocalDate( dt1 );
// LocalDate determination depends on the time zone.
// So be sure the date-time values are adjusted to the same time zone.
LocalDate ld2 = new LocalDate( dt2.withZone( dt1.getZone() ) );
Boolean match = ld1.equals( ld2 );
return match;
}
Лучше будет другой аргумент, указывающий часовой пояс, а не предполагающий, что следует использовать часовой пояс первого объекта DateTime.
static public Boolean sameDate ( DateTimeZone zone , DateTime dt1 , DateTime dt2 )
{
LocalDate ld1 = new LocalDate( dt1.withZone( zone ) );
// LocalDate determination depends on the time zone.
// So be sure the date-time values are adjusted to the same time zone.
LocalDate ld2 = new LocalDate( dt2.withZone( zone ) );
return ld1.equals( ld2 );
}
Строковое Представление
Другой подход состоит в том, чтобы создать строковое представление части даты каждой даты-времени, а затем сравнить строки.
Опять же, назначенный часовой пояс имеет решающее значение.
DateTimeFormatter formatter = ISODateTimeFormat.date(); // Static method.
String s1 = formatter.print( dateTime1 );
String s2 = formatter.print( dateTime2.withZone( dt1.getZone() ) );
Boolean match = s1.equals( s2 );
return match;
Промежуток времени
Обобщенное решение состоит в том, чтобы определить интервал времени, а затем спросить, содержит ли интервал вашу цель. Этот пример кода в Joda-Time 2.4. Обратите внимание, что относящиеся к «полуночи» классы устарели. Вместо этого используйте withTimeAtStartOfDay
метод. Joda-Time предлагает три класса для представления промежутка времени различными способами: Интервал, Период и Продолжительность.
Использование подхода «полуоткрытого», когда начало диапазона включено, а окончание - эксклюзивно.
Часовой пояс цели может отличаться от часового пояса интервала.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime target = new DateTime( 2012, 3, 4, 5, 6, 7, timeZone );
DateTime start = DateTime.now( timeZone ).withTimeAtStartOfDay();
DateTime stop = start.plusDays( 1 ).withTimeAtStartOfDay();
Interval interval = new Interval( start, stop );
boolean containsTarget = interval.contains( target );
java.time
Java 8 и более поздние версии поставляются с фреймворком java.time . Вдохновленный Joda-Time, определенным JSR 310 и расширенным проектом ThreeTen-Extra. Смотрите учебник .
Создатели Joda-Time поручили нам всем перейти на java.time, как только это будет удобно. Тем временем Joda-Time продолжает активно поддерживать проект. Но ожидайте, что будущая работа будет происходить только в java.time и ThreeTen-Extra, а не в Joda-Time.
Подводя итог java.time в двух словах ... Это Instant
момент времени на UTC. Примените часовой пояс ( ZoneId
), чтобы получить ZonedDateTime
объект. Для перехода от временной шкалы, чтобы получить смутное неопределенное представление о дате-времени, использовать «локальные» классов: LocalDateTime
, LocalDate
, LocalTime
.
Логика, обсуждаемая в разделе Joda-Time этого Ответа, применима к java.time.
Старый класс java.util.Date имеет новый toInstant
метод для преобразования в java.time.
Instant instant = yourJavaUtilDate.toInstant(); // Convert into java.time type.
Для определения даты требуется часовой пояс.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
Мы применяем этот объект часового пояса к, Instant
чтобы получить ZonedDateTime
. Из этого мы извлекаем значение только для даты (a LocalDate
), поскольку наша цель - сравнить даты (не часы, минуты и т. Д.).
ZonedDateTime zdt1 = ZonedDateTime.ofInstant( instant , zoneId );
LocalDate localDate1 = LocalDate.from( zdt1 );
Сделайте то же самое со вторым java.util.Date
объектом, который нам нужен для сравнения. Я просто использую текущий момент вместо этого.
ZonedDateTime zdt2 = ZonedDateTime.now( zoneId );
LocalDate localDate2 = LocalDate.from( zdt2 );
Используйте специальный isEqual
метод для проверки того же значения даты.
Boolean sameDate = localDate1.isEqual( localDate2 );