Java: самый простой способ вычесть даты

Я создал класс с двумя полями, которые должны быть даты, start_date и date_passed. Я изучал лучший способ на java, чтобы иметь даты в YYYY MM DD формат, который позволяет легко вычитание даты, и возможность "макияж" дату, скажем, в будущем, например.

пример того, что я хотел бы это сделать...

library.circulate_book("Chemistry", **start date here**) //actual date or random date
library.pass_book("Chemistry", **Date Passed here**) //random date such as 5 days after start date
int days_had = Date_Passed - start_date

до сих пор я нашел много способов форматирования дат с помощью календарей и классов дат, но еще не нашел тот, который выглядит так работа, рассматривающая большинство дат, заканчивается строками. Любые предложения / небольшие примеры очень ценятся! Кроме того, любые ссылки на примеры было бы здорово!

5 ответов


tl; dr

переходить от одной даты к другой путем добавления/вычитания количества дней.

LocalDate.now(
    ZoneId.of( "Pacific/Auckland" ) 
)
.minusDays( 5 )

чтобы вычислить количество дней, месяцев и лет, прошедших между двумя датами.

Period.between( start , stop )

извлечение

сначала вы должны проанализировать свои строковые входы в объекты даты и времени. Затем вы работаете над подготовкой своего бизнес-логики С этими объектами.

перестаньте думать о значениях даты и времени как о строках, которые будут сводит тебя с ума. Мы работаем с объектами date-time в нашем коде; мы обмениваемся данными с пользователями или другими приложениями, используя строковое представление этого объекта date-time.

в Java 8 и более поздних, используйте java.время основы. См.учебник.

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

этот фанковый синтаксис с двойным двоеточием -ссылка на метод, так сказать какой метод должен вызываться другим кодом.

String input = "2015 01 02";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "yyyy MM dd" );
LocalDate localDate = formatter.parse ( input , LocalDate :: from );

сейчас

определение сегодняшней даты требует часового пояса. Для любого данного момента дата варьируется по всему миру по зонам.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate todayTunis = LocalDate.now( z ) ;

если вы хотите текущий часовой пояс JVM по умолчанию, вызовите ZoneId.systemDefault.

Вычитая Даты

это было рассмотрено много раз раньше StackOveflow.com - ... Например,как вычесть X дней из даты с помощью Java календарь?. Дополнительные сведения см. в других ответах, таких как это я и это я для получения более подробной информации. Совет: "истекло" является ключевым словом поиска.

коротко, использовать Period определить количество стандартных дней, месяцев и лет.

LocalDate weekLater = localDate.plusDays ( 7 );
Period period = Period.between ( localDate , weekLater );
Integer daysElapsed = period.getDays ();

дамп в консоли.

System.out.println ( "localDate: " + localDate + " to " + weekLater + " in days: " + daysElapsed );

localDate: 2015-01-02 до 2015-01-09 в днях: 7

обратите внимание на ограничение:Period работает только с целыми днями, то есть только с датами без времени суток. Вот что нам нужно здесь для этого вопроса, так что работа сделана. Если у вас были значения даты и времени (ZonedDateTime объекты), используйте ThreeTen-Extra проекта Days класс, как указано в связанном вопросе/ответе выше.


лучший способ сделать это в Java-8 - это не ошибочный ответ Basil Bourque, но этот подход:

String startDate = "2016 01 02";
String passedDate = "2016 02 29";

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd");
LocalDate date1 = LocalDate.parse(startDate, formatter);
LocalDate date2 = LocalDate.parse(passedDate, formatter);

long elapsedDays = ChronoUnit.DAYS.between(date1, date2);
System.out.println(elapsedDays); // 58 (correct)

предлагаемое использование java.time.Period.getDays() опасно и часто неправильно, как только истекшая продолжительность превышает один месяц. Целое Period является P1M27D, поэтому этот код эффективно запрашивает только частичное количество прошедших дней (есть также истекший месяц):

System.out.println(Period.between(date1, date2).getDays()); // 27 (WRONG!!!)

удовлетворительное решение с использованием классов java.util.Date, GregorianCalendar etc. есть трудно найти. вы можете использовать ответ Tacktheritrix, но должны знать о том, что расчетное количество прошедших дней может отличаться из-за суб-дневных частей java.util.Date и также не надежен из-за игнорирования переключателей дневного света (где часы прыгают на один час во многих частях мира).

боковое примечание: по крайней мере 8 внешних библиотек предложите хорошие ответы к вашей проблеме, тоже. Но я думаю, что ваш простой случай использования не оправдывает встраивание дополнительной библиотеки, если вы еще не находитесь на Java-8. Любое альтернативное решение, как считать прошедшие дни между двумя датами, не было бы проще, чем в Java-8 - только подобное. И поскольку вы приняли связанный с Java-8 ответ Basil Bourque, я предполагаю, что вы действительно находитесь на Java-8, поэтому я оставляю ответ, как решить вашу проблему с другими библиотеками.


используйте Java 8 date api или joda, нет необходимости в новых изобретениях.

вы можете найти несколько примеров здесь:http://examples.javacodegeeks.com/core-java/java-8-datetime-api-tutorial/


С помощью Calendar:

Calendar cal = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();

cal2.setTime(cal.getTime());
cal2.add(Calendar.DAY_OF_YEAR, 5);
System.out.println((cal2.getTimeInMillis() - cal.getTimeInMillis()) / (1000d * 60 * 60 * 24));

Если вы застряли с более старой java, вы можете использовать SimpleDateFormat.

    //For substraction
    long differenceInMillis = date1.getTime() - date2.getTime();

    //Date Format
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy MM dd");
    String dateAsString = dateFormat.format(date1); //To get a text representation
    Date dateParsed = dateFormat.parse(dateAsString); //To get it back as date