Вычисление разницы между двумя экземплярами даты Java

Давайте сыграем наивную игру с идиомой SFINAE :

template  struct IsConstExpr
{
    typedef char yes;
    typedef char no[2];

    template  static constexpr yes& swallow(T) { int x[T()]; return 0; };
    template  static no& swallow(...);

    static const int value = sizeof(swallow(0)) == sizeof(yes);
};

. Вышеприведенный код синтаксически неверен, но это даст нам некоторое представление. Попробуем использовать его:

constexpr int f() { return 32167; }

int g() { return 32167; }

int main()
{
   std::cout << IsConstExpr::value << std::endl;
}

Компилятор говорит:

In instantiation of 'static constexpr IsConstExpr::yes& IsConstExpr::swallow(T) [with T = int (*)(); C = int (*)(); IsConstExpr:
:yes = char]':

Теперь проблема очевидна: параметром шаблона является T = int (*)();

Это означает, что constexpr не является частью типа, и мы не можем его обнаружить.

404
задан trentcl 31 August 2017 в 14:52
поделиться

12 ответов

API JDK Date , к сожалению, ужасно сломан. Я рекомендую использовать библиотеку времени Joda .

Joda Time имеет понятие времени Интервал :

Interval interval = new Interval(oldTime, new Instant());

РЕДАКТИРОВАТЬ: Между прочим, у Joda есть две концепции: Интервал для представления интервала времени между двумя моментами времени (представляют время между 8 и 10 часами утра) и Продолжительность , которая представляет отрезок времени без фактических временных границ (например, представляет два часа!)

Если вас интересует только сравнение времени, большинство реализаций Date (включая JDK) реализует интерфейс Comparable , который позволяет использовать Comparable.compareTo ()

186
ответ дан 22 November 2019 в 23:28
поделиться

Без использования стандартного API, № Вы можете сделать что-то вроде этого:

class Duration {
    private final TimeUnit unit;
    private final long length;
    // ...
}

Или вы можете использовать Joda :

DateTime a = ..., b = ...;
Duration d = new Duration(a, b);
2
ответ дан 22 November 2019 в 23:28
поделиться

Это, вероятно, самый простой способ сделать это - возможно, потому, что я уже некоторое время кодирую на Java (с ее, по общему признанию, неуклюжими библиотеками даты и времени), но этот код мне кажется «простым и приятным»!

Довольны ли вы результатом, возвращаемым в миллисекундах, или в рамках вашего вопроса вы бы предпочли, чтобы он возвращался в каком-либо альтернативном формате?

2
ответ дан 22 November 2019 в 23:28
поделиться

Взгляните на Joda Time ,

8
ответ дан 22 November 2019 в 23:28
поделиться

Немного более простая альтернатива:

System.currentTimeMillis() - oldDate.getTime()

Насчет «лучше»: ну а что именно вам нужно? Проблема с представлением продолжительности времени в виде количества часов, дней и т. Д. Состоит в том, что это может привести к неточностям и ошибочным ожиданиям из-за сложности дат (например, дни могут иметь 23 или 25 часов из-за перехода на летнее время).

24
ответ дан 22 November 2019 в 23:28
поделиться
int daysDiff = (date1.getTime() - date2.getTime()) / MILLIS_PER_DAY;
3
ответ дан 22 November 2019 в 23:28
поделиться

Посмотрите пример здесь http://www.roseindia.net/java/beginners/DateDifferent.shtml Этот пример показывает разницу в днях, часах, минутах, секундах и миллисекундах :).

import java.util.Calendar;
import java.util.Date;

public class DateDifferent {
    public static void main(String[] args) {
        Date date1 = new Date(2009, 01, 10);
        Date date2 = new Date(2009, 07, 01);
        Calendar calendar1 = Calendar.getInstance();
        Calendar calendar2 = Calendar.getInstance();
        calendar1.setTime(date1);
        calendar2.setTime(date2);
        long milliseconds1 = calendar1.getTimeInMillis();
        long milliseconds2 = calendar2.getTimeInMillis();
        long diff = milliseconds2 - milliseconds1;
        long diffSeconds = diff / 1000;
        long diffMinutes = diff / (60 * 1000);
        long diffHours = diff / (60 * 60 * 1000);
        long diffDays = diff / (24 * 60 * 60 * 1000);
        System.out.println("\nThe Date Different Example");
        System.out.println("Time in milliseconds: " + diff + " milliseconds.");
        System.out.println("Time in seconds: " + diffSeconds + " seconds.");
        System.out.println("Time in minutes: " + diffMinutes + " minutes.");
        System.out.println("Time in hours: " + diffHours + " hours.");
        System.out.println("Time in days: " + diffDays + " days.");
    }
}
4
ответ дан 22 November 2019 в 23:28
поделиться
int diffInDays = (int)( (newerDate.getTime() - olderDate.getTime()) 
                 / (1000 * 60 * 60 * 24) )

Обратите внимание, что это работает с датами UTC, поэтому разница может быть выходным днем, если вы посмотрите на местные даты. И чтобы он правильно работал с местными датами, требуется совершенно другой подход из-за перехода на летнее время.

150
ответ дан 22 November 2019 в 23:28
поделиться

Вам необходимо более четко определить вашу проблему. Вы можете просто взять количество миллисекунд между двумя объектами Date и разделить на количество миллисекунд в 24 часах, например ... но:

  • Это не будет учитывать часовые пояса - Дата всегда в формате UTC
  • При этом не учитывается переход на летнее время (например, могут быть дни длиной всего 23 часа)
  • Даже Сколько дней в рамках всемирного координированного времени с 11 вечера 16 августа по 2 часа ночи 18 августа? Это всего 27 часов, значит ли это, что один день? Или это должно быть три дня, потому что оно охватывает три даты?
53
ответ дан 22 November 2019 в 23:28
поделиться

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

final static long MILLIS_PER_DAY = 24 * 3600 * 1000;
long msDiff= date1.getTime() - date2.getTime();
long daysDiff = Math.round(msDiff / ((double)MILLIS_PER_DAY));

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

Обратите внимание, что это по-прежнему предполагает, что дата1 и дата2 установлены на одно и то же время суток. Для разного времени суток вам сначала нужно определить, что означает «разница в датах», как указал Джон Скит.

8
ответ дан 22 November 2019 в 23:28
поделиться

Просто вызовите getTime для каждой, возьмите разницу и разделите на количество миллисекунд в день.

-2
ответ дан 22 November 2019 в 23:28
поделиться

Если у вас есть d1 и d2 в качестве дат, лучшим решением, вероятно, будет следующее:

int days1 = d1.getTime()/(60*60*24*1000);//find the number of days since the epoch.
int days2 = d2.getTime()/(60*60*24*1000);

затем просто сказать

days2-days1

или что угодно

-3
ответ дан 22 November 2019 в 23:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: