Вычисление разницы между двумя примерами дат Java
Я использую класс Java java.util.Date
в Scala и хочу сравнить объект Date
и текущее время. Я знаю, что могу вычислить дельту, используя getTime():
(new java.util.Date()).getTime() - oldDate.getTime()
Однако это просто оставляет меня с long
, представляющим миллисекунды. Есть ли более простой и приятный способ получить временную дельту?
Ответы
Ответ 1
API JDK Date
, к сожалению, ужасно сломан. Я рекомендую использовать библиотеку Joda Time.
У Joda Time есть понятие времени Интервал:
Interval interval = new Interval(oldTime, new Instant());
ОБНОВЛЕНИЕ: Между прочим, у Joda есть две концепции: Interval
для представления интервала времени между двумя моментами времени (представляют время между 8:00 и 10:00) и Duration
, который представляет отрезок времени без фактического Границы времени (например, представляют два часа!)
Если вас интересуют только сравнения времени, большинство реализаций Date
(включая JDK) реализует интерфейс Comparable
, который позволяет вам использовать Comparable.compareTo()
Ответ 2
Простой diff (без lib)
/**
* Get a diff between two dates
* @param date1 the oldest date
* @param date2 the newest date
* @param timeUnit the unit in which you want the diff
* @return the diff value, in the provided unit
*/
public static long getDateDiff(Date date1, Date date2, TimeUnit timeUnit) {
long diffInMillies = date2.getTime() - date1.getTime();
return timeUnit.convert(diffInMillies,TimeUnit.MILLISECONDS);
}
А потом вы можете позвонить:
getDateDiff(date1,date2,TimeUnit.MINUTES);
чтобы получить разницу между двумя датами в минутах.
TimeUnit
- это java.util.concurrent.TimeUnit
, стандартное перечисление Java от наноса до дней.
Удобный для чтения diff (без lib)
public static Map<TimeUnit,Long> computeDiff(Date date1, Date date2) {
long diffInMillies = date2.getTime() - date1.getTime();
//create the list
List<TimeUnit> units = new ArrayList<TimeUnit>(EnumSet.allOf(TimeUnit.class));
Collections.reverse(units);
//create the result map of TimeUnit and difference
Map<TimeUnit,Long> result = new LinkedHashMap<TimeUnit,Long>();
long milliesRest = diffInMillies;
for ( TimeUnit unit : units ) {
//calculate difference in millisecond
long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS);
long diffInMilliesForUnit = unit.toMillis(diff);
milliesRest = milliesRest - diffInMilliesForUnit;
//put the result in the map
result.put(unit,diff);
}
return result;
}
http://ideone.com/5dXeu6
Вывод что-то вроде Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0}
, с заказанными единицами измерения.
Вам просто нужно преобразовать эту карту в удобную для пользователя строку.
Предупреждение
Приведенные выше фрагменты кода вычисляют простой diff между 2 моментами. Это может вызвать проблемы при переходе на летнее время, как описано в этом посте. Это означает, что если вы вычислите разницу между датами без времени, у вас может быть пропущенный день/час.
На мой взгляд, разница в датах является субъективной, особенно в дни. Вы можете:
подсчитать количество прошедших 24 часов: день + 1 - день = 1 день = 24 часа
подсчитать количество прошедшего времени, учитывая летнее время: день + 1 - день = 1 = 24 часа (но с использованием полуночи и летнего времени это может быть 0 дней и 23 часа)
посчитайте число day switches
, что означает день + 1 13:00 - день 11:00 = 1 день, даже если прошедшее время составляет всего 2 часа (или 1 час, если есть переход на летнее время: p)
Мой ответ действителен, если ваше определение различий по дням совпадает с первым случаем
С JodaTime
Если вы используете JodaTime, вы можете получить разность для 2-х дат (в миллисекундах с поддержкой ReadableInstant) дат:
Interval interval = new Interval(oldInstant, new Instant());
Но вы также можете получить разницу для локальных дат/времени:
// returns 4 because of the leap year of 366 days
new Period(LocalDate.now(), LocalDate.now().plusDays(365*5), PeriodType.years()).getYears()
// this time it returns 5
new Period(LocalDate.now(), LocalDate.now().plusDays(365*5+1), PeriodType.years()).getYears()
// And you can also use these static methods
Years.yearsBetween(LocalDate.now(), LocalDate.now().plusDays(365*5)).getYears()
Ответ 3
int diffInDays = (int)( (newerDate.getTime() - olderDate.getTime())
/ (1000 * 60 * 60 * 24) )
Обратите внимание, что это работает с датами UTC, поэтому разница может быть выходным днем, если вы посмотрите на локальные даты. И для правильной работы с местными датами требуется совершенно другой подход из-за летнего времени.
Ответ 4
Вам нужно более четко определить вашу проблему. Вы можете просто взять число миллисекунд между двумя объектами Date
и делить на число миллисекунд за 24 часа, например... но:
- Это не учитывает часовые пояса -
Date
всегда в UTC
- Это не займет времени на летнее время (например, дни могут составлять только 23 часа).
- Даже в UTC, сколько дней прошло с 16 августа 11:00 до 18 августа 2am? Это всего лишь 27 часов, значит ли это когда-нибудь? Или это должно быть три дня, потому что оно охватывает три даты?
Ответ 5
Использование рамки java.time, встроенной в Java 8 +:
ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime oldDate = now.minusDays(1).minusMinutes(10);
Duration duration = Duration.between(oldDate, now);
System.out.println("ISO-8601: " + duration);
System.out.println("Minutes: " + duration.toMinutes());
Выход:
ISO-8601: PT24H10M
Минуты: 1450
Для получения дополнительной информации см. Учебник Oracle и стандарт ISO 8601.
Ответ 6
ТЛ; др
Преобразуйте устаревшие объекты java.util.Date
в их замену, java.time.Instant
. Затем вычислите прошедшее время как Duration
.
Duration d =
Duration.between( // Calculate the span of time between two moments as a number of hours, minutes, and seconds.
myJavaUtilDate.toInstant() , // Convert legacy class to modern class by calling new method added to the old class.
Instant.now() // Capture the current moment in UTC. About two and a half hours later in this example.
)
;
d.toString(): PT2H34M56S
d.toMinutes(): 154
d.toMinutesPart(): 34
ISO 8601 Формат: PnYnMnDTnHnMnS
Разумный стандарт ISO 8601 определяет краткое текстовое представление промежутка времени в виде нескольких лет, месяцев, дней, часов и т.д. Стандарт называет такой такой промежуток продолжительностью. Формат PnYnMnDTnHnMnS
где P
означает "Период", T
отделяет часть даты от временной части, а между ними - цифры, за которыми следует буква.
Примеры:
-
P3Y6M4DT12H30M5S
три года, шесть месяцев, четыре дня, двенадцать часов, тридцать минут и пять секунд -
PT4H30M
Четыре с половиной часа
java.time
Рамка java.time, встроенная в Java 8 и более поздние версии, вытесняет неприятные старые классы java.util.Date
/java.util.Calendar
. Новые классы вдохновлены очень успешной структурой Joda-Time, предназначенной в качестве ее преемника, похожей на концепцию, но перепроектированной. Определяется JSR 310. Продлен проект ThreeTen-Extra. См. Учебник.
момент
Instant
класс представляет момент на временной шкале в UTC с разрешением наносекунд (до девяти (9) цифр десятичной дроби).
Instant instant = Instant.now() ; // Capture current moment in UTC.
Лучше избегать старых классов, таких как Date
/Calendar
. Но если вы должны взаимодействовать со старым кодом, который еще не обновлен до java.time, конвертируйте туда и обратно. Вызовите новые методы преобразования, добавленные к старым классам. Для перехода от java.util.Date
к Instant
, вызовите Date::toInstant
.
Instant instant = myJavaUtilDate.toInstant() ; // Convert from legacy 'java.util.Date' class to modern 'java.time.Instant' class.
Пространство времени
Классы java.time разделили эту идею представления промежутка времени в виде нескольких лет, месяцев, дней, часов, минут, секунд на две половины:
-
Period
по годам, месяцам, дням -
Duration
течение дней, часов, минут, секунд
Вот пример.
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now ( zoneId );
ZonedDateTime future = now.plusMinutes ( 63 );
Duration duration = Duration.between ( now , future );
Сбросьте консоль.
Оба Period
и Duration
используют стандарт ISO 8601 для генерации строкового представления их значения.
System.out.println ( "now: " + now + " to future: " + now + " = " + duration );
сейчас: 2015-11-26T00: 46: 48.016-05: 00 [Америка/Монреаль] в будущее: 2015-11-26T00: 46: 48.016-05: 00 [Америка/Монреаль] = PT1H3M
Java 9 добавляет методы к Duration
чтобы получить часть дней, часть часов, часть минут и часть секунд.
Вы можете получить общее количество дней или часов или минут или секунд или миллисекунд или наносекунды за всю продолжительность.
long totalHours = duration.toHours();
В Java 9 класс Duration
получает новые методы для возврата различных частей дней, часов, минут, секунд, миллисекунд/наносекунд. Позвоните в to…Part
Методы to…Part
: toDaysPart()
, toHoursPart()
и т.д.
ChronoUnit
Если вы заботитесь о более простой степени детализации времени, например "количество прошедших дней", используйте перечисление ChronoUnit
.
long daysElapsed = ChronoUnit.DAYS.between( earlier , later );
Другой пример.
Instant now = Instant.now();
Instant later = now.plus( Duration.ofHours( 2 ) );
…
long minutesElapsed = ChronoUnit.MINUTES.between( now , later );
120
О java.time
Рамка java.time встроена в Java 8 и более поздние версии. Эти классы вытесняют неприятные старые устаревшие классы времени, такие как java.util.Date
, Calendar
и SimpleDateFormat
.
Проект Joda-Time, теперь в режиме обслуживания, советует перейти на java.time.
Чтобы узнать больше, ознакомьтесь с учебным пособием Oracle. И поиск Qaru для многих примеров и объяснений. Спецификация - JSR 310.
Где можно получить классы java.time?
- Java SE 8 и SE 9 и более поздние версии
- Встроенный.
- Часть стандартного Java API с интегрированной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и SE 7
- Большая часть функциональных возможностей java.time включена обратно в Java 6 и 7 в ThreeTen-Backport.
- Android
Проект ThreeTen-Extra расширяет java.time с дополнительными классами. Этот проект является доказательством возможных будущих дополнений к java.time. Здесь вы можете найти полезные классы, такие как Interval
, YearWeek
, YearQuarter
и другие.
Joda времени
UPDATE: проект Joda-Time теперь находится в режиме обслуживания, а команда советует перейти на классы java.time. Я оставляю этот раздел неповрежденным для истории.
Библиотека Joda-Time использует ISO 8601 для своих значений по умолчанию. Его класс Period
анализирует и генерирует эти строки PnYnMnDTnHnMnS.
DateTime now = DateTime.now(); // Caveat: Ignoring the important issue of time zones.
Period period = new Period( now, now.plusHours( 4 ).plusMinutes( 30));
System.out.println( "period: " + period );
Оказывает:
period: PT4H30M
Ответ 7
Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();
https://www.joda.org/joda-time/faq.html#datediff
Ответ 8
Несколько более простая альтернатива:
System.currentTimeMillis() - oldDate.getTime()
Что касается "лучше": ну, что вам нужно? Проблема с представлением продолжительности времени в виде нескольких часов и дней и т.д. Заключается в том, что это может привести к неточностям и неправильным ожиданиям из-за сложности дат (например, дни могут иметь 23 или 25 часов из-за летнего времени).
Ответ 9
Использование миллисекундного подхода может вызвать проблемы в некоторых локалях.
Возьмем, например, разницу между двумя датами 03/24/2007 и 03/25/2007, должно быть 1 день;
Однако, используя миллисекундный маршрут, вы получите 0 дней, если вы запустите это в Великобритании!
/** Manual Method - YIELDS INCORRECT RESULTS - DO NOT USE**/
/* This method is used to find the no of days between the given dates */
public long calculateDays(Date dateEarly, Date dateLater) {
return (dateLater.getTime() - dateEarly.getTime()) / (24 * 60 * 60 * 1000);
}
Лучший способ реализовать это - использовать java.util.Calendar
/** Using Calendar - THE CORRECT WAY**/
public static long daysBetween(Calendar startDate, Calendar endDate) {
Calendar date = (Calendar) startDate.clone();
long daysBetween = 0;
while (date.before(endDate)) {
date.add(Calendar.DAY_OF_MONTH, 1);
daysBetween++;
}
return daysBetween;
}
Ответ 10
Есть много способов найти разницу между датами и временем. Один из самых простых способов, о которых я знаю, был бы:
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
calendar1.set(2012, 04, 02);
calendar2.set(2012, 04, 04);
long milsecs1= calendar1.getTimeInMillis();
long milsecs2 = calendar2.getTimeInMillis();
long diff = milsecs2 - milsecs1;
long dsecs = diff / 1000;
long dminutes = diff / (60 * 1000);
long dhours = diff / (60 * 60 * 1000);
long ddays = diff / (24 * 60 * 60 * 1000);
System.out.println("Your Day Difference="+ddays);
Вывод печати - это просто пример - вы можете отформатировать его, как вам нравится.
Ответ 11
Поскольку все ответы здесь правильные, но используйте устаревшие java или сторонние библиотеки, такие как joda или аналогичные, я просто поменяю другой способ, используя новые классы java.time в Java 8 и более поздних версиях. См. Учебник Oracle.
Используйте LocalDate
и ChronoUnit
:
LocalDate d1 = LocalDate.of(2017, 5, 1);
LocalDate d2 = LocalDate.of(2017, 5, 18);
long days = ChronoUnit.DAYS.between(d1, d2);
System.out.println( days );
Ответ 12
Вычитание дат в миллисекундах работает (как описано в другом сообщении), но вы должны использовать HOUR_OF_DAY, а не ЧАС, когда вы очищаете временные части ваших дат:
public static final long MSPERDAY = 60 * 60 * 24 * 1000;
...
final Calendar dateStartCal = Calendar.getInstance();
dateStartCal.setTime(dateStart);
dateStartCal.set(Calendar.HOUR_OF_DAY, 0); // Crucial.
dateStartCal.set(Calendar.MINUTE, 0);
dateStartCal.set(Calendar.SECOND, 0);
dateStartCal.set(Calendar.MILLISECOND, 0);
final Calendar dateEndCal = Calendar.getInstance();
dateEndCal.setTime(dateEnd);
dateEndCal.set(Calendar.HOUR_OF_DAY, 0); // Crucial.
dateEndCal.set(Calendar.MINUTE, 0);
dateEndCal.set(Calendar.SECOND, 0);
dateEndCal.set(Calendar.MILLISECOND, 0);
final long dateDifferenceInDays = ( dateStartCal.getTimeInMillis()
- dateEndCal.getTimeInMillis()
) / MSPERDAY;
if (dateDifferenceInDays > 15) {
// Do something if difference > 15 days
}
Ответ 13
Взгляните на Joda Time, который является улучшенным API Date/Time для Java и должен отлично работать со Scala.
Ответ 14
Если вы не хотите использовать 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 и секунд прыжка).
Обратите внимание, что это все еще предполагает, что date1
и date2
установлены в одно и то же время суток. В разное время суток вам сначала нужно определить, что означает "разница по дате", как указал Джон Скит.
Ответ 15
Позвольте мне показать разницу между Joda Interval и Days:
DateTime start = new DateTime(2012, 2, 6, 10, 44, 51, 0);
DateTime end = new DateTime(2012, 2, 6, 11, 39, 47, 1);
Interval interval = new Interval(start, end);
Period period = interval.toPeriod();
System.out.println(period.getYears() + " years, " + period.getMonths() + " months, " + period.getWeeks() + " weeks, " + period.getDays() + " days");
System.out.println(period.getHours() + " hours, " + period.getMinutes() + " minutes, " + period.getSeconds() + " seconds ");
//Result is:
//0 years, 0 months, *1 weeks, 1 days*
//0 hours, 54 minutes, 56 seconds
//Period can set PeriodType,such as PeriodType.yearMonthDay(),PeriodType.yearDayTime()...
Period p = new Period(start, end, PeriodType.yearMonthDayTime());
System.out.println(p.getYears() + " years, " + p.getMonths() + " months, " + p.getWeeks() + " weeks, " + p.getDays() + "days");
System.out.println(p.getHours() + " hours, " + p.getMinutes() + " minutes, " + p.getSeconds() + " seconds ");
//Result is:
//0 years, 0 months, *0 weeks, 8 days*
//0 hours, 54 minutes, 56 seconds
Ответ 16
Если вам нужна форматированная строка возврата типа
"2 Days 03h 42m 07s", попробуйте следующее:
public String fill2(int value)
{
String ret = String.valueOf(value);
if (ret.length() < 2)
ret = "0" + ret;
return ret;
}
public String get_duration(Date date1, Date date2)
{
TimeUnit timeUnit = TimeUnit.SECONDS;
long diffInMilli = date2.getTime() - date1.getTime();
long s = timeUnit.convert(diffInMilli, TimeUnit.MILLISECONDS);
long days = s / (24 * 60 * 60);
long rest = s - (days * 24 * 60 * 60);
long hrs = rest / (60 * 60);
long rest1 = rest - (hrs * 60 * 60);
long min = rest1 / 60;
long sec = s % 60;
String dates = "";
if (days > 0) dates = days + " Days ";
dates += fill2((int) hrs) + "h ";
dates += fill2((int) min) + "m ";
dates += fill2((int) sec) + "s ";
return dates;
}
Ответ 17
Посмотрите пример здесь 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.");
}
}
Ответ 18
Используйте часовой пояс, чтобы получить экземпляр Календаря, установите время, используя метод set класса Calendar. Часовой пояс GMT имеет 0 смещение (не очень важно), а флаг времени летнего времени - false.
final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
cal.set(Calendar.YEAR, 2011);
cal.set(Calendar.MONTH, 9);
cal.set(Calendar.DAY_OF_MONTH, 29);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
final Date startDate = cal.getTime();
cal.set(Calendar.YEAR, 2011);
cal.set(Calendar.MONTH, 12);
cal.set(Calendar.DAY_OF_MONTH, 21);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
final Date endDate = cal.getTime();
System.out.println((endDate.getTime() - startDate.getTime()) % (1000l * 60l * 60l * 24l));
Ответ 19
Примечание: startDate и endDates → java.util.Date
import org.joda.time.Duration;
import org.joda.time.Interval;
// Use .getTime() unless it is a joda DateTime object
Interval interval = new Interval(startDate.getTime(), endDate.getTime());
Duration period = interval.toDuration();
//gives the number of days elapsed between start
period.getStandardDays();
и дата окончания
Как и в дни, вы также можете получить часы, минуты и секунды
period.getStandardHours();
period.getStandardMinutes();
period.getStandardSeconds();
Ответ 20
Следующий код может дать желаемый результат:
String startDate = "Jan 01 2015";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd yyyy");
LocalDate date = LocalDate.parse(startDate, formatter);
String currentDate = "Feb 11 2015";
LocalDate date1 = LocalDate.parse(currentDate, formatter);
System.out.println(date1.toEpochDay() - date.toEpochDay());
Ответ 21
public static String getDifferenceBtwTime(Date dateTime) {
long timeDifferenceMilliseconds = new Date().getTime() - dateTime.getTime();
long diffSeconds = timeDifferenceMilliseconds / 1000;
long diffMinutes = timeDifferenceMilliseconds / (60 * 1000);
long diffHours = timeDifferenceMilliseconds / (60 * 60 * 1000);
long diffDays = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24);
long diffWeeks = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 7);
long diffMonths = (long) (timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 30.41666666));
long diffYears = (long)(timeDifferenceMilliseconds / (1000 * 60 * 60 * 24 * 365));
if (diffSeconds < 1) {
return "one sec ago";
} else if (diffMinutes < 1) {
return diffSeconds + " seconds ago";
} else if (diffHours < 1) {
return diffMinutes + " minutes ago";
} else if (diffDays < 1) {
return diffHours + " hours ago";
} else if (diffWeeks < 1) {
return diffDays + " days ago";
} else if (diffMonths < 1) {
return diffWeeks + " weeks ago";
} else if (diffYears < 12) {
return diffMonths + " months ago";
} else {
return diffYears + " years ago";
}
}
Ответ 22
int daysDiff = (date1.getTime() - date2.getTime()) / MILLIS_PER_DAY;
Ответ 23
Лучше всего сделать
(Date1-Date2)/86 400 000
Это число - миллисекунды в день.
Одна дата-другая дата дает вам разницу в миллисекундах.
Соберите ответ в переменной double.
Ответ 24
Не использовать стандартный API, no. Вы можете сделать свой собственный, сделав что-то вроде этого:
class Duration {
private final TimeUnit unit;
private final long length;
// ...
}
Или вы можете использовать Joda:
DateTime a = ..., b = ...;
Duration d = new Duration(a, b);
Ответ 25
Это, наверное, самый простой способ сделать это - возможно, потому, что я уже давно кодирую на Java (с его признанными неуклюжими библиотеками даты и времени), но этот код выглядит "простым и приятным" для меня!
Вы довольны результатом, возвращаемым в миллисекундах, или частью вашего вопроса, который вы предпочли бы вернуть его в каком-то альтернативном формате?
Ответ 26
Чтобы ответить на начальный вопрос:
Поместите следующий код в такую функцию, как Long getAge() {}
Date dahora = new Date();
long MillisToYearsByDiv = 1000l *60l * 60l * 24l * 365l;
long javaOffsetInMillis = 1990l * MillisToYearsByDiv;
long realNowInMillis = dahora.getTime() + javaOffsetInMillis;
long realBirthDayInMillis = this.getFechaNac().getTime() + javaOffsetInMillis;
long ageInMillis = realNowInMillis - realBirthDayInMillis;
return ageInMillis / MillisToYearsByDiv;
Наиболее важным здесь является работа с длинными числами при умножении и делении. И, конечно же, смещение, которое Java применяет в своем исчислении дат.
:)
Ответ 27
Поскольку вопрос помечен Scala,
import scala.concurrent.duration._
val diff = (System.currentTimeMillis() - oldDate.getTime).milliseconds
val diffSeconds = diff.toSeconds
val diffMinutes = diff.toMinutes
val diffHours = diff.toHours
val diffDays = diff.toDays
Ответ 28
Здесь правильное решение Java 7 в O (1) без каких-либо зависимостей.
public static int countDaysBetween(Date date1, Date date2) {
Calendar c1 = removeTime(from(date1));
Calendar c2 = removeTime(from(date2));
if (c1.get(YEAR) == c2.get(YEAR)) {
return Math.abs(c1.get(DAY_OF_YEAR) - c2.get(DAY_OF_YEAR)) + 1;
}
// ensure c1 <= c2
if (c1.get(YEAR) > c2.get(YEAR)) {
Calendar c = c1;
c1 = c2;
c2 = c;
}
int y1 = c1.get(YEAR);
int y2 = c2.get(YEAR);
int d1 = c1.get(DAY_OF_YEAR);
int d2 = c2.get(DAY_OF_YEAR);
return d2 + ((y2 - y1) * 365) - d1 + countLeapYearsBetween(y1, y2) + 1;
}
private static int countLeapYearsBetween(int y1, int y2) {
if (y1 < 1 || y2 < 1) {
throw new IllegalArgumentException("Year must be > 0.");
}
// ensure y1 <= y2
if (y1 > y2) {
int i = y1;
y1 = y2;
y2 = i;
}
int diff = 0;
int firstDivisibleBy4 = y1;
if (firstDivisibleBy4 % 4 != 0) {
firstDivisibleBy4 += 4 - (y1 % 4);
}
diff = y2 - firstDivisibleBy4 - 1;
int divisibleBy4 = diff < 0 ? 0 : diff / 4 + 1;
int firstDivisibleBy100 = y1;
if (firstDivisibleBy100 % 100 != 0) {
firstDivisibleBy100 += 100 - (firstDivisibleBy100 % 100);
}
diff = y2 - firstDivisibleBy100 - 1;
int divisibleBy100 = diff < 0 ? 0 : diff / 100 + 1;
int firstDivisibleBy400 = y1;
if (firstDivisibleBy400 % 400 != 0) {
firstDivisibleBy400 += 400 - (y1 % 400);
}
diff = y2 - firstDivisibleBy400 - 1;
int divisibleBy400 = diff < 0 ? 0 : diff / 400 + 1;
return divisibleBy4 - divisibleBy100 + divisibleBy400;
}
public static Calendar from(Date date) {
Calendar c = Calendar.getInstance();
c.setTime(date);
return c;
}
public static Calendar removeTime(Calendar c) {
c.set(HOUR_OF_DAY, 0);
c.set(MINUTE, 0);
c.set(SECOND, 0);
c.set(MILLISECOND, 0);
return c;
}
Ответ 29
После прохождения всех остальных ответов, чтобы сохранить тип даты Java 7, но быть более точным/стандартным с подходом Java 8 diff,
public static long daysBetweenDates(Date d1, Date d2) {
Instant instant1 = d1.toInstant();
Instant instant2 = d2.toInstant();
long diff = ChronoUnit.DAYS.between(instant1, instant2);
return diff;
}
Ответ 30
попробуйте следующее:
int epoch = (int) (new java.text.SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse("01/01/1970 00:00:00").getTime() / 1000);
вы можете отредактировать строку в параметре parse() param.