У Java, як отримати різницю в секундах між двома датами?


79

Бібліотека класів Java має клас з іменем DateTime. DateTime має такий метод:

int daysBetween(DateTime other)

який повертає кількість днів між цим і параметром. У нього немає методу

int secondsBetween(DateTime other)

який мені випадково потрібен. Чи існує клас, подібний до DateTime, але має такий метод?


1
Це може допомогти: xmission.com/~goodhill/dates/deltaDates.html
Prasoon Saurav

1
Якщо ви на Java 8 у вас є кілька варіантів см stackoverflow.com/q/25747499/32453
rogerdpack

Відповіді:


184

Не знайомий з DateTime ...

Якщо у вас є дві дати, ви можете зателефонувати їм getTime, щоб отримати мілісекунди, отримайте різницю та розділіть на 1000. Наприклад

Date d1 = ...;
Date d2 = ...;
long seconds = (d2.getTime()-d1.getTime())/1000;

Якщо у вас є об’єкти Календаря, ви можете зателефонувати

c.getTimeInMillis()

і зробити те саме


2
Коли різниця в часі не така висока - int seconds = (int) ((d2.getTime () - d1.getTime ()) / 1000);
Xdg 07.03.13

@sebrock - виправлено, щоб показувати тип, як довго - кастинг на int буде працювати на менші суми
Скотт Стенчфілд

1
@Xdg Нещодавно я розробляв інтерфейс і зіткнувся з тією ж "проблемою", але Integer.MAX_VALUEможе представляти майже 70 років за секунди. Цього мені було достатньо.
mike

Я шукаю відповідь за допомогою LocalDateTime.
JohnMerlino

12

Я хотів би надати сучасну відповідь. Інші відповіді були чудовими, коли було задано це питання, але час рухається далі. Сьогодні я рекомендую вам використовувати java.timeсучасний API дати та часу Java .

    ZonedDateTime aDateTime = ZonedDateTime.of(2017, 12, 8, 19, 25, 48, 991000000, ZoneId.of("Europe/Sarajevo"));
    ZonedDateTime otherDateTime = ZonedDateTime.of(2017, 12, 8, 20, 10, 38, 238000000, ZoneId.of("Europe/Sarajevo"));

    long diff = ChronoUnit.SECONDS.between(aDateTime, otherDateTime);
    System.out.println("Difference: " + diff + " seconds");

Це друкує:

Difference: 2689 seconds

ChronoUnit.SECONDS.between()працює з двома ZonedDateTimeпредметами або двома OffsetDateTimes, двома LocalDateTimes тощо.

Якщо вам потрібно щось інше, ніж лише секунди, вам слід розглянути можливість використання Durationкласу:

    Duration dur = Duration.between(aDateTime, otherDateTime);
    System.out.println("Duration: " + dur);
    System.out.println("Difference: " + dur.getSeconds() + " seconds");

Це друкує:

Duration: PT44M49.247S
Difference: 2689 seconds

Перший із двох рядків друкує тривалість у форматі ISO 8601, вихід означає тривалість 44 хвилини 49,247 секунди.

Чому java.time?

DateКлас , який використовується в ряді інших відповідей тепер давно застарів. Joda-Time, який також використовується в парі (і, можливо, у цьому питанні), зараз перебуває в режимі обслуговування, серйозні вдосконалення не плануються, і розробники офіційно рекомендують перейти на java.time, також відомий як JSR-310.

Питання: Чи можу я використовувати сучасний API зі своєю версією Java?

Якщо ви використовуєте принаймні Java 6 , ви можете.


Дуже недооцінена відповідь. Розрахунки Джодатайма тут трохи безладні. Однак ChronoUnit.SECONDS.between(oldDate.toInstant(), newDate.toInstant())це досить легко запам'ятати.
anon58192932

10

Ви повинні це зробити

org.joda.time.Seconds.secondBetween(date1, date2)

3
Ласкаво просимо до StackOverflow та дякуємо за внесок. Це було б сильнішим постом, якби ви пояснили, чому це такий шлях.
Філ

5
@divonas не має різниці. Його позначення прямо посилається на йоду
Тім,

1
Правильна назва методу - 'second s Between'. Це означає, що це найчистіший спосіб, який я знайшов за допомогою org.joda.time.DateTime.
thisismydesign

1
Якщо ви хочете отримати результати як int, вам слід викликати getSeconds () щодо результату. Seconds.secondsBetween(start, end).getSeconds()
thisismydesign

1
Я думаю, що зараз існує спосіб Java 8, який не вимагає jodatime. Я в пошуках цього.
anon58192932

7

Це має зробити це:

Date a = ...;
Date b = ...;

Math.abs(a.getTime()-b.getTime())/1000;

Ось відповідна документація: Date.getTime () . Майте на увазі, що це буде працювати лише для дат після 1 січня 1970 року, 00:00:00 за Грінвичем


Хм, чому це може працювати лише на дати після 1 січня 1970 року? До цього значення є від’ємними, але арифметика працює з від’ємними числами.
Джей

5

Не існує такого класу, як DateTimeу стандартному API Java SE. Хоча в joda-time він є, навіть у нього немає daysBetweenметоду.

Використовуючи стандартний Java API, найпростіший спосіб отримати секунди між двома java.util.Dateоб’єктами - це відняти їх мітки часу і розділити на 1000:

int secondsBetween = (date1.getTime() - date2.getTime()) / 1000;

3

Не рекомендується використовувати java.util.Dateабо System.currentTimeMillis()вимірювати минулий час. Ці дати не гарантуються одноманітними і будуть змінюватися при зміні системного годинника (наприклад, при виправленні з сервера). Ймовірно, це трапляється рідко, але чому б не кодувати краще рішення, а не турбуватися про можливі негативні або дуже великі зміни?

Натомість я б рекомендував використовувати System.nanoTime().

long t1 = System.nanoTime();
long t2 = System.nanoTime();

long elapsedTimeInSeconds = (t2 - t1) / 1000000000;

РЕДАГУВАТИ

Для отримання додаткової інформації про монетичність див. Відповідь на відповідне запитання, яке я задав, де nanoTime використовує монотонні годинники, де це можливо. Я тестував, але використовував лише Windows XP, Java 1.6 та модифікував годинник, що nanoTimeбуло монотонним, а currentTimeMillisні.

Також з документації Java у режимі реального часу :

Питання: 50. Чи повертається час через годинник реального часу з кращою роздільною здатністю, ніж час, повернутий System.nanoTime ()?

Годинник реального часу та System.nanoTime () базуються на одному системному дзвінку і, отже, на одному годиннику.

У Java RTS усі API, орієнтовані на час (наприклад, таймери, періодичні потоки, моніторинг дедлайну тощо), базуються на таймері з високою роздільною здатністю. І разом із пріоритетами в режимі реального часу вони можуть забезпечити виконання відповідного коду в потрібний час для обмежень у режимі реального часу. На відміну від цього, звичайні API Java SE пропонують лише кілька методів, здатних обробляти час із високою роздільною здатністю, без гарантії виконання в даний момент часу. Використання System.nanoTime () між різними точками коду для виконання вимірювань минулого часу завжди повинно бути точним.


Хм, цікавий пост. Що змушує вас говорити, що nanoTime не підлягає оновленню годинника? Я не бачу нічого в документації Java щодо цього. Я не кажу, що ви помиляєтесь, мені, мабуть, цікаво, чи є у вас посилання чи ви проводили експерименти, щоб підтвердити це.
Джей


2

Ви можете використовувати, org.apache.commons.lang.time.DateUtilsщоб зробити його чистішим:

(firstDate.getTime() - secondDate.getTime()) / DateUtils.MILLIS_PER_SECOND

0

Який клас ? Ви маєте на увазі клас Joda DateTime ? Якщо так, ви можете просто зателефонувати getMillis()кожному та виконати відповідне віднімання / масштабування.

Я б порекомендував Joda для роботи з датою та часом, до речі, завдяки його корисному та інтуїтивно зрозумілому API, а також безпеці потоків для форматування / аналізу.


Це не стандартна бібліотека (як і Joda), ні особливо відома (на відміну від Joda)
Брайан Егню

0

Просто вказівник: Якщо ви обчислюєте різницю між двома java.util.Date, підхід віднімання обох дат і ділення на 1000 є розумним, але будьте особливо обережні, якщо отримаєте посилання на java.util.Date з об’єкта Календаря . Якщо ви зробите це, вам потрібно взяти до уваги перехід на літній час вашого часового поясу, оскільки одна з дат, яку ви використовуєте, може мати місце в зимовий час.

Це пояснюється за посиланням Prasoon, я рекомендую витратити трохи часу, щоб прочитати його.


0

Використовуйте цей метод:

private Long secondsBetween(Date first, Date second){
    return (second.getTime() - first.getTime())/1000;
}

2
Додайте пояснення до своєї відповіді, будь ласка.
Alex Char,

Зрозуміло, що вам потрібно надіслати дві дати, я маю на увазі Date dateDate = new Date () та Date finalDate = new Date (), тому, якщо ви надішлете InitiDate і finalDate, ви зможете отримати різницю в кодах ... обидва вони будуть "конвертуйте" в Long за допомогою методу getTIme і нарешті ви отримаєте різницю, поділену на 1000, щоб отримати секунди ... чудова відповідь до речі!
Рауль Герреро,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.