дней между двумя датами сравнить -> проще?

привет, я спрашиваю себя, есть ли более простой способ получить количество дней между двумя датами.

Я хочу только дни, не глядя ни на часы, ни на минуты.

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

Поэтому я использую этот код:

        Calendar c = Calendar.getInstance();
        // Only the day:
        c.set(Calendar.HOUR, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);

        Calendar to = Calendar.getInstance();
        to.setTime(date);
        to.set(Calendar.HOUR, 0);
        to.set(Calendar.MINUTE, 0);
        to.set(Calendar.SECOND, 0);
        to.set(Calendar.MILLISECOND, 0);
        date = to.getTime();

        long millsPerDay = 1000 * 60 * 60 * 24;

        long dayDiff = ( date.getTime() - dateToday.getTime() ) / millsPerDay;

после этого кода у меня есть дни в длинном названии dayDiff. но действительно ли обязательно делать календарь даты, устанавливать время на 00:00:00:00 и сохранять to.getTime() в date?

Редактировать: после использования joda-time: возможно ли также с помощью joda-time получить информацию о днях, например: разница==1 ==> Завтра или разница == -1 ==> вчера или мне нужно сделать это вручную?


person eav    schedule 27.04.2011    source источник


Ответы (5)


Вы можете использовать API JodaTime, как показано здесь.

person npinti    schedule 27.04.2011
comment
поддерживает ли он также функцию Day Light Save (как сказал Ральф) - person eav; 27.04.2011

Для указанной задачи я всегда использую этот удобный способ: (без библиотеки, только API Java 5)

import java.util.concurrent.TimeUnit;

Date d1 = ...
Date d2 = ...

long daysBetween = TimeUnit.MILLISECONDS.toDays(d2.getTime() - d1.getTime());

Наслаждаться!

person user and    schedule 27.04.2011

public long dayDiff(Date d1, Date d2) {
    final long DAY_MILLIS = 1000 * 60 * 60 * 24;
    long day1 = d1.getTime() / DAY_MILLIS;
    long day2 = d2.getTime() / DAY_MILLIS;
    return (day1 - day2);
}

Прости за мою невнимательность

person J.S. Taylor    schedule 27.04.2011
comment
Почему вы используете double и константу float? Если бы вы использовали long, вам не нужно было бы разыгрывать или вызывать floor - person Peter Lawrey; 27.04.2011
comment
Да, я бы использовал long и сделал его константой. Будьте осторожны с делением на встроенное умножение, как у вас изначально, поскольку оно будет интерпретироваться как int. Он отлично работает для дневного интервала, однако, если вы разделите на 1000 * 60 * 60 * 24 * 30 месяц, он переполнит int, и вы не получите ожидаемого результата. - person WhiteFang34; 27.04.2011
comment
Спасибо, ребята, думаю, когда-нибудь я получу Нобелевскую премию по глупостям. :) исправляю мой код сейчас - person J.S. Taylor; 27.04.2011

Вместо того, чтобы устанавливать все нерелевантные значения в 0, вы можете использовать commons lang DateUtils.truncate

В любом случае, dayDiff (начало-конец)/milliesPerDay не будет работать корректно из-за изменений режима Day Light Save.

person Ralph    schedule 27.04.2011

Вот аналитический метод daydiff, не основанный на опасных миллисекундных преобразованиях:

public static int dayDiff(Calendar to, Calendar from){
    int result = 0;
    int years;


    // global year difference from 1.jan to 1.jan
    years = to.get(Calendar.YEAR) - from.get(Calendar.YEAR);
    result = years * 365; 

    // adding days for simple leap years ( divisible by 4 ). This an approximation that will be corrected by the negative leap years formula.
    result += (to.get(Calendar.YEAR)-1)/4 - (from.get(Calendar.YEAR)-1)/4;

    // removing days for negative leap years ( divisible by 100 ). This is still an approximation that will be corrected by the big leap years formula.
    result -= (to.get(Calendar.YEAR)-1)/100 - (from.get(Calendar.YEAR)-1)/100;

    // adding days for big leap years ( divisible by 400 ). After this formula, the days count from 1.jan.<from> to 1.jan.<to> is correct.
    result += (to.get(Calendar.YEAR)-1)/400 - (from.get(Calendar.YEAR)-1)/400;

    // adding month of to-year
    for(int m=0; m<to.get(Calendar.MONTH ); m++){
        result += daysInMonth(m, to.get(Calendar.YEAR));
    }

    // substracting month of from-year
    for(int m=0; m<from.get(Calendar.MONTH ); m++){
        result -= daysInMonth(m, from.get(Calendar.YEAR));
    }

    // adding days of to-year
    result += to.get(Calendar.DAY_OF_MONTH ); 


    // substracting days of from-year
    result -= from.get(Calendar.DAY_OF_MONTH ); 

    return result;

}

private static int daysInMonth(int m, int y){
    if(m==3 || m==5 || m==8 || m==10) return 30;
    if(m==1)
        if(isLeapYear(y)) return 29;
        else return 28;
    return 31;
}


private static boolean isLeapYear(int y){
    return (isSimpleLeapYear(y) && !isNegativeLeapYear(y)) || isBigLeapYear(y);
}

private static boolean isSimpleLeapYear(int y){
    return y%4 == 0;
}

private static boolean isNegativeLeapYear(int y){
    return y%100 == 0;
}

private static boolean isBigLeapYear(int y){
    return y%400 == 0;
}

}

person toggeli    schedule 13.06.2012
comment
Лично я предпочитаю использовать существующие библиотеки дат, а не свои собственные. Работа с датами имеет множество нюансов, которые легко не заметить. - person Leigh; 14.06.2012