Вычисление разницы между двумя примерами дат 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

Ответ 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.