Давайте сыграем наивную игру с идиомой 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
не является частью типа, и мы не можем его обнаружить.
API JDK Date
, к сожалению, ужасно сломан. Я рекомендую использовать библиотеку времени Joda .
Joda Time имеет понятие времени Интервал :
Interval interval = new Interval(oldTime, new Instant());
РЕДАКТИРОВАТЬ: Между прочим, у Joda есть две концепции: Интервал
для представления интервала времени между двумя моментами времени (представляют время между 8 и 10 часами утра) и Продолжительность
, которая представляет отрезок времени без фактических временных границ (например, представляет два часа!)
Если вас интересует только сравнение времени, большинство реализаций Date
(включая JDK) реализует интерфейс Comparable
, который позволяет использовать Comparable.compareTo ()
Без использования стандартного API, № Вы можете сделать что-то вроде этого:
class Duration {
private final TimeUnit unit;
private final long length;
// ...
}
Или вы можете использовать Joda :
DateTime a = ..., b = ...;
Duration d = new Duration(a, b);
Это, вероятно, самый простой способ сделать это - возможно, потому, что я уже некоторое время кодирую на Java (с ее, по общему признанию, неуклюжими библиотеками даты и времени), но этот код мне кажется «простым и приятным»!
Довольны ли вы результатом, возвращаемым в миллисекундах, или в рамках вашего вопроса вы бы предпочли, чтобы он возвращался в каком-либо альтернативном формате?
Немного более простая альтернатива:
System.currentTimeMillis() - oldDate.getTime()
Насчет «лучше»: ну а что именно вам нужно? Проблема с представлением продолжительности времени в виде количества часов, дней и т. Д. Состоит в том, что это может привести к неточностям и ошибочным ожиданиям из-за сложности дат (например, дни могут иметь 23 или 25 часов из-за перехода на летнее время).
int daysDiff = (date1.getTime() - date2.getTime()) / MILLIS_PER_DAY;
Посмотрите пример здесь 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.");
}
}
int diffInDays = (int)( (newerDate.getTime() - olderDate.getTime())
/ (1000 * 60 * 60 * 24) )
Обратите внимание, что это работает с датами UTC, поэтому разница может быть выходным днем, если вы посмотрите на местные даты. И чтобы он правильно работал с местными датами, требуется совершенно другой подход из-за перехода на летнее время.
Вам необходимо более четко определить вашу проблему. Вы можете просто взять количество миллисекунд между двумя объектами Date
и разделить на количество миллисекунд в 24 часах, например ... но:
Дата
всегда в формате UTC Если вы не хотите использовать 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
установлены на одно и то же время суток. Для разного времени суток вам сначала нужно определить, что означает «разница в датах», как указал Джон Скит.
Просто вызовите getTime для каждой, возьмите разницу и разделите на количество миллисекунд в день.
Если у вас есть 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
или что угодно