tl; dr
Используйте современные java.time классы, а не ужасные унаследованные классы.Никогда не используйте Date
или DateFormat
или SimpleDateFormat
.
Пример кода в синтаксисе Java:
Period
.between(
LocalDate.parse(
"Monday, May 11 2015" ,
DateTimeFormatter.ofPattern( "EEEE, MMM d uuuu" , Locale.US )
) ,
LocalDate.now( ZoneId.of( "America/Los_Angeles" ) )
)
.toString() ;
P3Y8M18D
Избегайте наследстваклассы даты и времени
Вы используете ужасные классы даты и времени, которые годы назад были отменены классами java.time , с принятием JSR 310.
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.
DateTimeFormatter
Определите шаблон форматирования, соответствующий вашему вводу.(Синтаксис Java)
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEEE, MMM d uuuu" , Locale.US ) ;
String input = "Monday, May 11 2015" ;
LocalDate ld = LocalDate.parse( input , f ) ;
ld.toString (): 2015-05-11
Истекшее время
Для расчета прошедшего времени в годах-месяцы-дни, используйте Period
.Для дней (24-часовой период времени, а не календарных дней), часов и секунд используйте Duration
.
Period p = Period.between( ld , today ) ;
p.toString (): P3Y8M18D
Эта строка в стандартных форматах ISO 8601 означает «три года, восемь месяцев и восемнадцать дней».
См. Приведенный выше код, запущенный в режиме реального времени на IdeOne.com .
В java.time нет функции локализации для представления Period
или Duration
со словами.Вместо этого вы можете сгенерировать свою собственную строку.
String output = p.getYears() + " years, " + p.getMonths() + " months, " + p.getDays() + " days" ; // Obviously, you could get fancier by checking for zero or singular values and then adjust the text.
ISO 8601
Избегайте обмена значениями даты и времени, используя локализованные форматы, такие как те, что видны во входных данных.Вместо этого при обмене значениями даты и времени в виде текста всегда используйте стандартные форматы ISO 8601 .Они были продуманно разработаны, чтобы избежать двусмысленности.Их легко разобрать на машине и легко прочитать людям в разных культурах.
Классы java.time по умолчанию используют форматы ISO 8601 при разборе / генерации строк.Поэтому нет необходимости указывать какой-либо шаблон форматирования.
Для значения только для даты стандартным форматом является ГГГГ-ММ-ДД, например 2019-01-23
.
LocalDate ld = LocalDate.parse( "2019-01-23" ) ;
О java.time
Среда java.time встроена в Java 8и позже.Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
и & SimpleDateFormat
.
Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .
Чтобы узнать больше, см. Oracle Tutorial .И поиск переполнения стека для многих примеров и объяснений.Спецификация: JSR 310 .
Вы можете обмениваться java.time объектами напрямую с вашей базой данных.Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии.Нет необходимости в строках, нет необходимости в java.sql.*
классах.
Где получить классы java.time?
ThreeTen-Extra Проект расширяет java.time дополнительными классами.Этот проект является полигоном для возможных будущих дополнений к java.time.Вы можете найти здесь несколько полезных классов, таких как Interval
, YearWeek
, YearQuarter
и more .