ТЛ; др
LocalDate // Represent a date-only value, without time-of-day and without time zone.
.now( // Capture today's date as seen in the wall-clock time used by the people of a particular region (a time zone).
ZoneId.of( "Asia/Tokyo" ) // Specify the desired/expected zone.
) // Returns a `LocalDate` object.
.minus( // Subtract a span-of-time.
Period.ofDays( 30 ) // Represent a span-of-time unattached to the timeline in terms of years-months-days.
) // Returns another `LocalDate` object.
Избегайте устаревших классов даты и времени
Связанная группа классов java.util.Date & .Calendar общеизвестно хлопотна. Избегайте их.
java.time
Современный подход использует классы java.time , встроенные в Java 8 и более поздние версии и перенесенные обратно в Java 6 & 7.
LocalDate
Класс LocalDate
представляет значение только для даты без времени суток и без часового пояса или смещения от UTC .
Часовой пояс имеет решающее значение при определении даты. В любой момент времени дата меняется по всему земному шару в зависимости от зоны. Например, через несколько минут после полуночи в Париж Франция - это новый день, а еще "вчера" в Монреаль Квебек .
Если часовой пояс не указан, JVM неявно применяет свой текущий часовой пояс по умолчанию. Это значение по умолчанию может измениться в любой момент во время выполнения (!), Поэтому ваши результаты могут отличаться. Лучше явно указать желаемый / ожидаемый часовой пояс в качестве аргумента. Если критично, подтвердите зону с вашим пользователем.
Укажите собственное имя часового пояса в формате Continent/Region
, например America/Montreal
, Africa/Casablanca
или Pacific/Auckland
. Никогда не используйте 2-4 буквенные сокращения, такие как EST
или IST
, поскольку они не истинные часовые пояса, не стандартизированы и даже не уникальны (!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
Если вы хотите использовать текущий часовой пояс JVM по умолчанию, запросите его и передайте в качестве аргумента. Если опущен, код становится неоднозначным для чтения, поскольку мы не знаем наверняка, намеревались ли вы использовать значение по умолчанию или если вы, как и многие программисты, не знали об этой проблеме.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Или укажите дату. Вы можете установить месяц по номеру, с нормальным номером 1-12 для января-декабря.
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Или, лучше, использовать предварительно определенные объекты перечисления Month
, по одному на каждый месяц года. Совет: используйте эти Month
объекты по всей вашей кодовой базе, а не просто целое число, чтобы сделать ваш код более самодокументируемым, обеспечить допустимые значения и обеспечить type-safety . То же самое для Year
& YearMonth
.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
Дата математика
Вы можете определить промежуток времени в виде лет-месяцев-дней с помощью класса Period
.
Period days_30 = Period.ofDays( 30 ) ;
Period days_60 = Period.ofDays( 60 ) ;
Period days_90 = Period.ofDays( 90 ) ;
Вы можете добавлять и вычитать Period
в / из LocalDate
, в результате чего получается еще один LocalDate
объект. Вызовите методы LocalDate::plus
или LocalDate::minus
.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate today = LocalDate.now( z ) ;
LocalDate ago_30 = today.minus( days_30 ) ;
LocalDate ago_60 = today.minus( days_60 ) ;
LocalDate ago_90 = today.minus( days_90 ) ;
Вы более непосредственно вызываете LocalDate.minusDays
, но я подозреваю, что названные объекты Period
сделают ваш код более читабельным и самодокументируемым.
LocalDate ago = today.minusDays( 30 ) ;
1095 * JDBC *
Звучит так, будто вы запрашиваете базу данных. Начиная с JDBC 4.2 и выше, вы можете обмениваться объектами java.time с вашей базой данных. Для столбца базы данных типа данных, аналогичного стандарту SQL DATE
(значение только для даты, без времени суток и без часового пояса), используйте класс LocalDate
в Java.
myPreparedStatement.setObject( … , ago_30 ) ;
индексирование:
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
О java.time
Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
, & SimpleDateFormat
.
Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .
Проект Joda-Time , теперь в режиме обслуживания , рекомендует выполнить переход на классы java.time .
Вы можете обмениваться java.time объектами напрямую с вашей базой данных. Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.*
классах.
Где получить классы java.time?
Java SE 8 , Java SE 9 , Java SE 10 , Java SE 11 и более поздние версии - часть стандартного Java API с связанной реализацией.
Java 9 добавляет некоторые незначительные функции и исправления.
Java SE 6 и Java SE 7
Большинство функций java.time перенесены в Java 6 & 7 в ThreeTen-Backport .
Android
Более поздние версии реализаций комплекта Android классов java.time .
Для более ранних версий Android (<26) проект <a href="https://github.com/JakeWharton/ThreeTenABP" rel="nofollow noreferrer"> ThreeTenABP адаптируется ThreeTen-Backport (упомянуто выше). См. Как использовать ThreeTenABP… .
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval
, YearWeek
, YearQuarter
и more .
Joda-Time
ОБНОВЛЕНИЕ: Библиотека Joda-Time теперь находится в режиме обслуживания. Его создатель, Стивен Колебурн, продолжал руководить реализацией JSR 310 и java.time на основе уроков, извлеченных из Joda-Time. Я оставляю этот раздел нетронутым как историю, но советую вместо этого использовать java.time .
Ниже приведен пример кода с использованием библиотеки Joda-Time 2.3 LocalDate .
LocalDate now = LocalDate.now();
LocalDate thirty = now.minusDays( 30 );
LocalDate sixty = now.minusDays( 60 );
LocalDate ninety = now.minusDays( 90 );
Дамп на консоль ...
System.out.println( "now: " + now );
System.out.println( "thirty: " + thirty );
System.out.println( "sixty: " + sixty );
System.out.println( "ninety: " + ninety );
При запуске…
now: 2014-03-26
thirty: 2014-02-24
sixty: 2014-01-25
ninety: 2013-12-26
Часовой пояс
Начало и окончание дня зависит от вашего часового пояса. Новый день в Париже наступает раньше, чем в Монреале.
По умолчанию класс LocalDate использует часовой пояс по умолчанию вашей JVM для определения текущей даты. Кроме того, вы можете передать объект DateTimeZone.
LocalDate localDate = new LocalDate( DateTimeZone.forID( "Europe/Paris" ) );