Вопрос-ответ

Calculating days between two dates with Java

Вычисление дней между двумя датами с помощью Java

Мне нужна Java-программа, которая вычисляет дни между двумя датами.


  1. Введите первую дату (немецкие обозначения; с пробелами: "дд мм гггг")

  2. Введите вторую дату.

  3. Программа должна вычислить количество дней между двумя датами.

Как я могу включить високосные годы и летнее время?

Мой код:

import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;

public class NewDateDifference {

public static void main(String[] args) {

System.out.print("Insert first date: ");
Scanner s = new Scanner(System.in);
String[] eingabe1 = new String[3];

while (s.hasNext()) {
int i = 0;
insert1[i] = s.next();
if (!s.hasNext()) {
s.close();
break;
}
i++;
}

System.out.print("Insert second date: ");
Scanner t = new Scanner(System.in);
String[] insert2 = new String[3];

while (t.hasNext()) {
int i = 0;
insert2[i] = t.next();
if (!t.hasNext()) {
t.close();
break;
}
i++;
}

Calendar cal = Calendar.getInstance();

cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(insert1[0]));
cal.set(Calendar.MONTH, Integer.parseInt(insert1[1]));
cal.set(Calendar.YEAR, Integer.parseInt(insert1[2]));
Date firstDate = cal.getTime();

cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(insert2[0]));
cal.set(Calendar.MONTH, Integer.parseInt(insert2[1]));
cal.set(Calendar.YEAR, Integer.parseInt(insert2[2]));
Date secondDate = cal.getTime();


long diff = secondDate.getTime() - firstDate.getTime();

System.out.println ("Days: " + diff / 1000 / 60 / 60 / 24);
}
}
Переведено автоматически
Ответ 1

ОБНОВЛЕНИЕ: Первоначальный ответ от 2013 года теперь устарел, потому что некоторые классы были заменены. Новый способ сделать это - использовать новые java.time классы.

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd MM yyyy");
String inputString1 = "23 01 1997";
String inputString2 = "27 04 1997";

try {
LocalDateTime date1 = LocalDate.parse(inputString1, dtf);
LocalDateTime date2 = LocalDate.parse(inputString2, dtf);
long daysBetween = Duration.between(date1, date2).toDays();
System.out.println ("Days: " + daysBetween);
} catch (ParseException e) {
e.printStackTrace();
}

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

long daysBetween = ChronoUnit.DAYS.between(date1, date2)

Оригинальный ответ (устарел по состоянию на Java 8)

Вы производите некоторые преобразования со своими строками, которые не являются необходимыми. Для этого есть SimpleDateFormat класс - попробуйте этот:

SimpleDateFormat myFormat = new SimpleDateFormat("dd MM yyyy");
String inputString1 = "23 01 1997";
String inputString2 = "27 04 1997";

try {
Date date1 = myFormat.parse(inputString1);
Date date2 = myFormat.parse(inputString2);
long diff = date2.getTime() - date1.getTime();
System.out.println ("Days: " + TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS));
} catch (ParseException e) {
e.printStackTrace();
}

РЕДАКТИРОВАТЬ: Поскольку были некоторые обсуждения относительно корректности этого кода: он действительно учитывает високосные годы. Однако TimeUnit.DAYS.convert функция теряет точность, поскольку миллисекунды преобразуются в дни (смотрите Связанный документ для получения дополнительной информации). Если это проблема, diff также можно преобразовать вручную:

float days = (diff / (1000*60*60*24));

Обратите внимание, что это float значение, не обязательно int.

Ответ 2

Самый простой способ:

public static long getDifferenceDays(Date d1, Date d2) {
long diff = d2.getTime() - d1.getTime();
return TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
}
Ответ 3

В Java 8 вы могли бы выполнить это с помощью LocalDate и DateTimeFormatter. Из Javadoc из LocalDate:


LocalDate - это неизменяемый объект date-time, который представляет дату, часто рассматриваемую как год-месяц-день.


И шаблон может быть создан с помощью DateTimeFormatter. Вот Javadoc и соответствующие символы шаблона, которые я использовал:


Символ - Значение - Презентация - Примеры


y - год эры - год - 2004; 04


M / L - месяц года - число / текст - 7; 07; Июль; July; J


d - день месяца - число - 10


Вот пример:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

public class Java8DateExample {
public static void main(String[] args) throws IOException {
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MM yyyy");
final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
final String firstInput = reader.readLine();
final String secondInput = reader.readLine();
final LocalDate firstDate = LocalDate.parse(firstInput, formatter);
final LocalDate secondDate = LocalDate.parse(secondInput, formatter);
final long days = ChronoUnit.DAYS.between(firstDate, secondDate);
System.out.println("Days between: " + days);
}
}

Пример ввода / вывода с более свежим last:

23 01 1997
27 04 1997
Days between: 94

С более свежим первым:

27 04 1997
23 01 1997
Days between: -94

Ну, вы могли бы сделать это как метод более простым способом:

public static long betweenDates(Date firstDate, Date secondDate) throws IOException
{
return ChronoUnit.DAYS.between(firstDate.toInstant(), secondDate.toInstant());
}
Ответ 4

Большинство / все ответы вызвали у нас проблемы с переходом на летнее время. Вот наше рабочее решение для всех дат, без использования JodaTime. В нем используются объекты календаря.:

public static int daysBetween(Calendar day1, Calendar day2){
Calendar dayOne = (Calendar) day1.clone(),
dayTwo = (Calendar) day2.clone();

if (dayOne.get(Calendar.YEAR) == dayTwo.get(Calendar.YEAR)) {
return Math.abs(dayOne.get(Calendar.DAY_OF_YEAR) - dayTwo.get(Calendar.DAY_OF_YEAR));
} else {
if (dayTwo.get(Calendar.YEAR) > dayOne.get(Calendar.YEAR)) {
//swap them
Calendar temp = dayOne;
dayOne = dayTwo;
dayTwo = temp;
}
int extraDays = 0;

int dayOneOriginalYearDays = dayOne.get(Calendar.DAY_OF_YEAR);

while (dayOne.get(Calendar.YEAR) > dayTwo.get(Calendar.YEAR)) {
dayOne.add(Calendar.YEAR, -1);
// getActualMaximum() important for leap years
extraDays += dayOne.getActualMaximum(Calendar.DAY_OF_YEAR);
}

return extraDays - dayTwo.get(Calendar.DAY_OF_YEAR) + dayOneOriginalYearDays ;
}
}
java