Вопрос

Я использую Java java.util.Date класс в Scala и хотите сравнить Date объект и текущее время.Я знаю, что могу вычислить дельту, используя getTime():

(new java.util.Date()).getTime() - oldDate.getTime()

Однако это просто оставляет меня с long представляющий миллисекунды.Есть ли какой-нибудь более простой и приятный способ получить временную дельту?

Это было полезно?

Решение

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

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

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

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

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

Другие советы

Простой дифф (без библиотеки)

/**
 * 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, начиная с nanos и заканчивая днями.


Читабельный для человека diff (без библиотеки)

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}, с заказанными единицами.

Вам просто нужно преобразовать эту карту в удобную для пользователя строку.


Предупреждение

Приведенные выше фрагменты кода вычисляют простую разницу между двумя моментами.Это может вызвать проблемы при переходе на летнее время, как описано в разделе эта почта.Это означает, что если вы вычисляете разницу между датами без указания времени, у вас может быть пропущен день/час.

На мой взгляд, разница в датах довольно субъективна, особенно по дням.Вы можете:

  • подсчитайте количество прошедших 24 часов:день+1 - день = 1 день = 24 часа

  • подсчитайте количество прошедшего времени, позаботившись о переходе на летнее время:день+1 - день = 1 = 24 часа (но при использовании полуночного времени и летнего времени это может быть 0 дней и 23 часа)

  • подсчитать количество day switches, что означает день+1 13:00 - день 11:00 = 1 день, даже если прошедшее время составляет всего 2 часа (или 1 час, если есть летнее время :p)

Мой ответ действителен, если ваше определение разницы дат в днях соответствует первому случаю.

С ДжодаТаймом

Если вы используете JodaTime, вы можете получить разницу для двух мгновенных дат (поддерживаемых миллимилями 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()
int diffInDays = (int)( (newerDate.getTime() - olderDate.getTime()) 
                 / (1000 * 60 * 60 * 24) )

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

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

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

Используя 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());

Выход:

ИСО-8601:ПТ24Х10М

Минуты:1450

Для получения дополнительной информации см. Учебное пособие по Oracle и ИСО 8601 стандарт.

tl;dr

Преобразуйте свой устаревший 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

д.тоМинутес():154

d.Томинутая часть ():34

Формат ISO 8601: PnYnMnDTnHnMnS

Разумный стандарт ISO 8601 определяет краткое текстовое представление промежутка времени в виде количества лет, месяцев, дней, часов и т.д.Стандарт называет такой-то промежуток a Продолжительность.Формат таков PnYnMnDTnHnMnS где находится P означает "Период", то есть T отделяет часть даты от части времени, а между ними находятся цифры, за которыми следует буква.

Примеры:

  • P3Y6M4DT12H30M5S
    три года, шесть месяцев, четыре дня, двенадцать часов, тридцать минут и пять секунд
  • PT4H30M
    Четыре с половиной часа

java.время

Тот Самый java.время фреймворк, встроенный в Java 8 и более поздние версии, вытесняет надоедливый старый java.util.Date/java.util.Calendar классы.Новые классы вдохновлены весьма успешными Джода-Время фреймворк, задуманный как его преемник, схожий по концепции, но с измененной архитектурой.Определяется JSR 310.Расширен за счет Три дня-Дополнительно проект.Смотрите на Учебник.

Мгновение

Тот Самый Instant класс представляет собой момент на временной шкале в UTC с разрешением наносекунды (до девяти (9) цифр десятичной дроби).

Instant instant = Instant.now() ;  // Capture current moment in UTC.

Лучше всего избегать устаревших классов, таких как Date/Calendar.Но если вам необходимо взаимодействовать со старым кодом, который еще не обновлен до java.время, конвертировать туда и обратно.Вызовите новые методы преобразования, добавленные к старым классам.Для перехода от 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 методы: 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.время фреймворк встроен в Java 8 и более поздние версии.Эти классы вытесняют старые, вызывающие беспокойство наследие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

Тот Самый Джода-Время проект, находящийся сейчас в режим технического обслуживания, советует перейти на java.time.

Чтобы узнать больше, смотрите Учебное пособие по Oracle.И найдите в Stack Overflow множество примеров и объяснений.Спецификация такова JSR 310.

Где взять классы java.time?

  • Java SE 8 и SE 9 и позже
    • Встроенный.
    • Часть стандартного Java API со встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и SE 7
    • Большая часть функциональности java.time обратно перенесена на Java 6 и 7 в ThreeTen-Задний порт.
  • Android

Тот Самый Три дня-Дополнительно проект расширяет java.time дополнительными классами.Этот проект является испытательным полигоном для возможных будущих дополнений к java.time.Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter, и Еще.


Джода-Время

Обновить:Тот Самый Джода-Время проект сейчас находится в режим технического обслуживания, с командой , консультирующей по переходу на java.время классы.Я оставляю этот раздел нетронутым для истории.

Библиотека 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
Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();

https://www.joda.org/joda-time/faq.html#datediff

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

System.currentTimeMillis() - oldDate.getTime()

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

Использование миллисекундного подхода может вызвать проблемы в некоторых регионах.

Возьмем, к примеру, разницу между двумя датами 24.03.2007 и 25.03.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;  
}  

Есть много способов найти разницу между датами и временем.Один из самых простых способов, которые я знаю, это:

      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);

Оператор печати — это всего лишь пример — вы можете отформатировать его так, как вам нравится.

Поскольку все ответы здесь верны, но используйте устаревшие библиотеки 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 );

Вычитание дат в миллисекундах работает (как описано в другом посте), но вы иметь чтобы использовать HOUR_OF_DAY, а не HOUR при очистке временных частей ваших дат:

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
}

Если вы не хотите использовать 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));

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

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

Взгляни на Джода Время, который представляет собой улучшенный API даты/времени для Java и должен нормально работать со Scala.

Позвольте мне показать разницу между интервалом Джода и днями:

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 

Если вам нужна возвращаемая строка в форматированном виде, например "2 дня 03: 42: 07", попробуйте это:

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;
}

Проверьте пример здесь 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.");
    }
}

Используйте часовой пояс GMT, чтобы получить экземпляр календаря, установите время с помощью метода 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));

Следующий код может дать вам желаемый результат:

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());
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";
    }
}   

Примечание: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();
int daysDiff = (date1.getTime() - date2.getTime()) / MILLIS_PER_DAY;

Лучшее, что можно сделать, это

(Date1-Date2)/86 400 000 

Это число является числом миллисекунды в день.

Одна дата-другая дата дает разницу в миллисекундах.

Соберите ответ в двойной переменная.

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

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

Не используя стандартный API, нет.Вы можете свернуть свой собственный, сделав что-то вроде этого:

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

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

DateTime a = ..., b = ...;
Duration d = new Duration(a, b);

Просто чтобы ответить на первоначальный вопрос:

Поместите следующий код в функцию типа 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 применяет при исчислении дат.

:)

Поскольку вопрос помечен как 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

Вот правильное решение 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;
}

После рассмотрения всех остальных ответов, чтобы сохранить тип даты Java 7, но быть более точным/стандартным с помощью подхода сравнения Java 8,

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;
}

попробуй это:

int epoch = (int) (new java.text.SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse("01/01/1970  00:00:00").getTime() / 1000);

вы можете редактировать строку в параметре метода parse().

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top