Как сравнить две даты без временной части? - PullRequest
181 голосов
/ 17 сентября 2009

Я хотел бы иметь метод CompareTo, который игнорирует часть времени java.util.Date. Я думаю, что есть несколько способов решить эту проблему. Какой самый простой способ?

Ответы [ 30 ]

6 голосов
/ 29 октября 2009

Боюсь, что не существует метода сравнения двух дат, который можно было бы назвать «простым» или «простым».

При сравнении двух экземпляров времени с любым видом пониженной точности (например, просто сравнение дат) вы всегда должны учитывать влияние часового пояса на сравнение.

Если date1 указывает событие, которое произошло в +2 часовом поясе, а date2 указывает событие, которое произошло в EST, например, вы должны позаботиться о том, чтобы правильно понять последствия сравнения.

Ваша цель - выяснить, произошли ли два события в одну и ту же календарную дату в их соответствующих часовых поясах? Или Вам нужно знать, попадают ли две даты в одну и ту же календарную дату в определенном часовом поясе (например, в формате UTC или в вашем местном TZ).

Как только вы выясните, что же вы на самом деле пытаетесь сравнить, это просто вопрос получения тройки год-дата-дата в соответствующем часовом поясе и проведения сравнения.

Время Joda может заставить реальную операцию сравнения выглядеть намного чище, но семантика сравнения все еще является чем-то, что вам нужно выяснить самостоятельно.

4 голосов
/ 26 мая 2012

Если вы просто хотите сравнить только две даты без времени, вам может помочь следующий код:

final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
Date dLastUpdateDate = dateFormat.parse(20111116);
Date dCurrentDate = dateFormat.parse(dateFormat.format(new Date()));
if (dCurrentDate.after(dLastUpdateDate))
{
   add your logic
}
4 голосов
/ 10 ноября 2011

Вот решение из этого блога: http://brigitzblog.blogspot.com/2011/10/java-compare-dates.html

long milliseconds1 = calendar1.getTimeInMillis();
long milliseconds2 = calendar2.getTimeInMillis();
long diff = milliseconds2 - milliseconds1;
long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.println("Time in days: " + diffDays  + " days.");

т.е. Вы можете видеть, меньше ли разница во времени в миллисекундах, чем продолжительность одного дня.

4 голосов
/ 25 марта 2015

`

SimpleDateFormat sdf= new SimpleDateFormat("MM/dd/yyyy")

   Date date1=sdf.parse("03/25/2015");



  Date currentDate= sdf.parse(sdf.format(new Date()));

   return date1.compareTo(currentDate);

`

2 голосов
/ 30 ноября 2017

Я не знаю, по-новому ли это или иначе, но я покажу вам, как сделал

SimpleDateFormat dtf = new SimpleDateFormat("dd/MM/yyyy");
Date td_date = new Date();
String first_date = dtf.format(td_date);    //First seted in String 
String second_date = "30/11/2020";          //Second date you can set hear in String

String result = (first_date.equals(second_date)) ? "Yes, Its Equals":"No, It is not Equals";
System.out.println(result);
2 голосов
/ 21 июня 2015

В Java 8 вы можете использовать LocalDate, который очень похож на тот, что был в Joda Time.

1 голос
/ 19 июня 2017
public Date saveDateWithoutTime(Date date) {
    Calendar calendar = Calendar.getInstance();

    calendar.setTime( date );
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.HOUR, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    return calendar.getTime();
}

Это поможет вам сравнить даты без учета времени.

1 голос
/ 25 марта 2017

Во-первых, имейте в виду, что эта операция зависит от часового пояса. Так что выберите, хотите ли вы сделать это в UTC, в часовом поясе компьютера, в своем любимом часовом поясе или где. Если вы еще не уверены, что это важно, посмотрите мой пример внизу этого ответа.

Поскольку ваш вопрос не совсем ясен по этому поводу, я предполагаю, что у вас есть класс с полем экземпляра, представляющим момент времени и реализующий Comparable, и вы хотите, чтобы естественное упорядочение ваших объектов осуществлялось с помощью дата, но не время этого поля. Например:

public class ArnesClass implements Comparable<ArnesClass> {

    private static final ZoneId arnesTimeZone = ZoneId.systemDefault();

    private Instant when;

    @Override
    public int compareTo(ArnesClass o) {
        // question is what to put here
    }

}

Java 8 java.time классы

Я взял на себя свободу изменить тип поля вашего экземпляра с Date на Instant, соответствующий класс в Java 8. Я обещаю вернуться к обработке Date ниже. Я также добавил постоянную часового пояса. Вы можете установить его на ZoneOffset.UTC или ZoneId.of("Europe/Stockholm") или на то, что считаете нужным (установка на ZoneOffset работает, потому что ZoneOffset является подклассом ZoneId).

Я решил показать решение с использованием классов Java 8. Вы просили самый простой способ, верно? :-) Вот метод compareTo, который вы просили:

public int compareTo(ArnesClass o) {
    LocalDate dateWithoutTime = when.atZone(arnesTimeZone).toLocalDate();
    LocalDate otherDateWithoutTime = o.when.atZone(arnesTimeZone).toLocalDate();
    return dateWithoutTime.compareTo(otherDateWithoutTime);
}

Если вам никогда не нужна временная часть when, конечно, легче объявить when a LocalDate и пропустить все преобразования. Тогда нам больше не нужно беспокоиться о часовом поясе.

Теперь предположим, что по какой-то причине вы не можете объявить свое when поле Instant или хотите оставить его старомодным Date. Если вы все еще можете использовать Java 8, просто преобразуйте его в Instant, а затем сделайте как раньше:

    LocalDate dateWithoutTime = when.toInstant().atZone(arnesTimeZone).toLocalDate();

Аналогично для o.when.

Нет Java 8?

Если вы не можете использовать Java 8, есть два варианта:

  1. Решите это, используя один из старых классов, Calendar или SimpleDateFormat.
  2. Используйте бэкпорт классов даты и времени Java 8 для Java 6 и 7, затем сделайте то же, что и выше. Я включаю ссылку внизу. Не используйте JodaTime. JodaTime был, вероятно, хорошим предложением, когда ответы, рекомендующие его, были написаны; но JodaTime сейчас находится в режиме обслуживания, поэтому бэкпорт ThreeTen является лучшим и более перспективным вариантом.

Старомодные способы

Ответ Адамски показывает, как убрать часть времени с Date, используя класс Calendar. Я предлагаю вам использовать getInstance(TimeZone), чтобы получить Calendar экземпляр для часового пояса, который вы хотите. В качестве альтернативы вы можете использовать идею второй половины ответа Йорна .

Использование SimpleDateFormat на самом деле является косвенным способом использования Calendar, поскольку SimpleDateFormat содержит объект Calendar. Тем не менее, вы можете найти это менее проблематичным, чем прямое использование Calendar:

private static final TimeZone arnesTimeZone = TimeZone.getTimeZone("Europe/Stockholm");
private static final DateFormat formatter = new SimpleDateFormat("yyyyMMdd");
static {
    formatter.setTimeZone(arnesTimeZone);
}

private Date when;

@Override
public int compareTo(ArnesClass o) {
    return formatter.format(when).compareTo(formatter.format(o.when));
}

Это было вдохновлено Ответом Роба .

Зависимость от часового пояса

Почему мы должны выбирать определенный часовой пояс? Скажем, мы хотим сравнить два раза, что в UTC 24 марта 0:00 (полночь) и 12:00 (полдень). Если вы сделаете это в CET (скажем, Европа / Париж), это будет 1 час ночи и 1 час дня 24 марта, то есть в тот же день. В Нью-Йорке (по восточному поясному времени) они наступают в 20:00 23 марта и в 8:00 24 марта, то есть не в одну дату. Так что важно, какой часовой пояс вы выберете. Если вы просто полагаетесь на настройки компьютера по умолчанию, вас могут удивить неожиданные попытки запуска вашего кода на компьютере в другом месте в этом глобализированном мире.

Link

Ссылка на ThreeTen Backport, бэкпорт классов даты и времени Java 8 для Java 6 и 7: http://www.threeten.org/threetenbp/.

1 голос
/ 21 декабря 2015

Использование http://mvnrepository.com/artifact/commons-lang/commons-lang

Date date1 = new Date();

Date date2 = new Date();

if (DateUtils.truncatedCompareTo(date1, date2, Calendar.DAY_OF_MONTH) == 0)
    // TRUE
else
    // FALSE
1 голос
/ 30 августа 2015

Другой простой метод сравнения, основанный на ответах, приведенных здесь, и наставлениях моего наставника

public static int compare(Date d1, Date d2) {
    Calendar c1 = Calendar.getInstance();
    Calendar c2 = Calendar.getInstance();
    c1.setTime(d1);
    c1.set(Calendar.MILLISECOND, 0);
    c1.set(Calendar.SECOND, 0);
    c1.set(Calendar.MINUTE, 0);
    c1.set(Calendar.HOUR_OF_DAY, 0);
    c2.setTime(d2);
    c2.set(Calendar.MILLISECOND, 0);
    c2.set(Calendar.SECOND, 0);
    c2.set(Calendar.MINUTE, 0);
    c2.set(Calendar.HOUR_OF_DAY, 0);
    return c1.getTime().compareTo(c2.getTime());
  }

EDIT : По словам @Jonathan Drapeau, приведенный выше код завершается ошибкой в ​​некоторых случаях (я хотел бы увидеть эти случаи, пожалуйста) , и он предложил следующее, как я понимаю:

public static int compare2(Date d1, Date d2) {
    Calendar c1 = Calendar.getInstance();
    Calendar c2 = Calendar.getInstance();
    c1.clear();
    c2.clear();
    c1.set(Calendar.YEAR, d1.getYear());
    c1.set(Calendar.MONTH, d1.getMonth());
    c1.set(Calendar.DAY_OF_MONTH, d1.getDay());
    c2.set(Calendar.YEAR, d2.getYear());
    c2.set(Calendar.MONTH, d2.getMonth());
    c2.set(Calendar.DAY_OF_MONTH, d2.getDay());
    return c1.getTime().compareTo(c2.getTime());
}

Обратите внимание, что класс Date устарел, поскольку он не поддается интернационализации. Вместо него используется класс Calendar!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...