java.time
Ведущая в отрасли инфраструктура даты и времени: java.time , встроенная в Java 8 и более поздние версии, определяемая как JSR 310 .
Человек, ведущий этот проект - Стивен Коулборн . Он также возглавлял своего предшественника, очень успешный проект Joda-Time . Уроки, извлеченные с Joda-Time , были применены при разработке совершенно новых java.time классов. Кстати, Joda-Time был портирован на .Net в проекте NodaTime .
найдите количество дней между двумя указанными датами,
Используйте класс Period
для представления промежутка времени в гранулированности лет-месяцев-дней.
LocalDate start = LocalDate.of( 2019 , Month.JANUARY , 23 ) ;
LocalDate stop = LocalDate.of( 2019 , Month.MARCH , 3 ) ;
Period p = Period.between( start , stop ) ;
Или, если вы хотите просто указать общее количество дней, используйте ChronoUnit
.
long days = ChronoUnit.DAYS.between( start , stop ) ;
количество минут между двумя заданными минутными периодами и т. Д.
Используйте класс Duration
для представления промежутка времени с детализацией дней (24-часовой период времени, не связанный с календарем), часов, минут, секунд, доли секунды.
Instant start = Instant.now() ; // Capture the current moment as seen in UTC.
…
Instant stop = Instant.now() ;
Duration d = Duration.between( start , stop ) ;
Если вы хотите, чтобы общее количество минут истекло за весь промежуток времени, позвоните по номеру toMinutes
.
long elapsedMinutes = d.toMinutes() ;
сложение и вычитание интервалов из отметок времени
Вы можете выполнять математику даты и времени, используя классы Period
и Duration
, упомянутые выше, передавая методы plus
& minus
в различных классах.
Instant now = Instant.now() ;
Duration d = Duration.ofMinutes( 7 ) ;
Instant later = now.plus( d ) ;
позволяет простое преобразование часовых поясов, при этом изменения летнего времени по регионам автоматически учитываются
Класс ZoneId
хранит историю прошлых, настоящих и будущих изменений смещения, используемого людьми определенного региона, то есть часового пояса.
Укажите правильное имя часового пояса в формате Continent/Region
, например America/Montreal
, Africa/Casablanca
или Pacific/Auckland
. Никогда не используйте 2-4-буквенное сокращение, например EST
или IST
, так как они не истинных часовых поясов, не стандартизированы и даже не уникальны (!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ; // Get the current date as seen by the people of a certain region.
Если вы хотите использовать текущий часовой пояс JVM по умолчанию, запросите его и передайте в качестве аргумента. Если опущен, код становится неоднозначным для чтения, поскольку мы точно не знаем, намеревались ли вы использовать значение по умолчанию или если вы, как и многие программисты, не знали об этой проблеме.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Мы можем использовать ZoneId
для настройки между зонами. Во-первых, давайте посмотрим на текущий момент в формате UTC.
Instant instant = Instant.now() ;
Применение часового пояса к часовому поясу в Тунисе. Примените ZoneId
к Instant
, чтобы получить объект ZonedDateTime
. Тот же момент, та же точка на временной шкале, но другое время на настенных часах.
ZoneId zTunis = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdtTunis = instant.atZone( zTunis ) ;
Давайте посмотрим в тот же момент, что и в Японии, который смотрит на часы на своей стене.
ZoneId zTokyo = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdtTokyo = zdtTunis.withZoneSameInstant( zTokyo ) ; // Same moment, different wall-clock time.
Все три объекта, instant
, zdtTunis
и zdtTokyo
, представляют один и тот же момент. Представьте себе трехстороннюю телефонную конференцию между кем-то в Исландии (где они используют UTC), кем-то в Тунисе и кем-то в Японии. Если каждый человек в один и тот же момент смотрит на часы и календарь на соответствующей стене, каждый из них увидит на своих часах разное время суток и, возможно, другую дату в своем календаре.
Обратите внимание, что java.time использует неизменных объектов . Вместо того, чтобы изменять («изменять») объект, возвращайте новый новый объект на основе значений оригинала.
(учитывая, что имеется точная база данных поддержки региональных настроек)
Java включает в себя копию tzdata , базы данных стандартного часового пояса. Убедитесь, что ваша JVM обновлена, чтобы соответствовать текущим определениям часовых поясов. К сожалению, политики во всем мире проявляют склонность к пересмотру часовых поясов своей юрисдикции практически без предварительного предупреждения. Поэтому вам может потребоваться обновить tzddata вручную, если часовой пояс, о котором вы беспокоитесь, внезапно изменится.
ПоКстати, ваша операционная система, скорее всего, также имеет собственную копию tzdata . Держите это свежим для ваших потребностей не-Java. То же самое для любых других систем, которые вы могли установить, таких как сервер баз данных, например Postgres с собственной копией tzdata .
получить период, в который попадает данная временная метка, с учетом детализации периода («в каком календарном дне находится эта дата?»)
Под «календарным днем» вы подразумеваете день недели? В java.time у нас есть DayOfWeek
enum, который предопределяет семь объектов, по одному на каждый день недели.
DayOfWeek dow = LocalDate.now( z ).getDayOfWeek() ;
Под «календарным днем» вы подразумеваете день года (1-366)?
int dayOfYear = LocalDate.now( z ).getDayOfYear() ;
Под «календарным днем» вы подразумеваете представление год-месяц ?
YearMonth ym = YearMonth.from( today ) ; // `today` being `LocalDate.now( ZoneId.of( "Pacific/Auckland" ) )`.
Возможно, месяц-день?
MonthDay md = MonthDay.from( today ) ;
поддержка очень общих преобразований строки в дату (с учетом шаблона)
Вы можете указать пользовательский шаблон форматирования, который будет использоваться при разборе / генерации строки, представляющей значение объекта даты и времени. Смотрите метод DateTimeFormatter.ofPattern
. Поиск переполнения стека для получения дополнительной информации, так как это было обработано много раз.
Если ваша строка правильно отформатирована в соответствии с правилами локализации для конкретной культуры, вы можете позволить java.time выполнить синтаксический анализ, не удосуживаясь определить шаблон форматирования.
Locale locale = Locale.CANADA_FRENCH ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM ).withLocale( locale ) ;
String output = LocalDate.now( z ).format( f ) ;
если есть настройка календаря / GregorianCalendar в стиле Java
Классы Calendar
и GregorianCalendar
, включенные в ранние версии Java, ужасны. Никогда не используйте их. Они полностью вытесняются классами java.time , в частности классом ZonedDateTime
.
приспосабливаясь к подклассам, если мне нужно свернуть свой собственный иврит, вавилонский, толкинский или марсианский календарь. (Java-календари делают это бессмысленно, например.)
Многие системы календаря уже были внедрены для java.time . Каждый из них известен как хронология . Календарная система, обычно используемая на Западе и во многих сферах бизнеса по всему миру, представляет собой хронологию ISO 8601 . Это используется по умолчанию в java.time , java.time.chrono.IsoChronology
.
В комплекте с Java вы также найдете дополнительные хронологии, включая версию исламского календаря хиджра , систему календаря японской империи, систему календаря Minguo (Тайвань и т. Д.) И Тайский буддистский календарь.
Вы найдете больше хронологий, определенных в проекте ThreeTen-Extra . См. Пакет org.threeten.extra.chrono
для получения списка, включающего: стандартный бухгалтерский календарь IRS / IFRS, британский юлиан-григорианский календарный календарь, коптский христианский календарь, систему Discordian календаря, эфиопский календарь, международный фиксированный календарь (календарь Eastman Kodak) , юлианский календарь и многое другое.
Но если вам нужен какой-то другой календарь, java.time предоставляет AbstractChronology
, чтобы начать работу. Но сделайте серьезный поиск в Интернете, прежде чем начинать самостоятельно, так как он уже может быть построен. И все перечисленные выше хронологии с открытым исходным кодом, так что вы можете изучить их для руководства.
"Сколько минут у вас между 2002 и следующим Днем Святого Валентина?"
LocalDate date2002 = Year.of( 2002 ).atDay( 1 );
MonthDay valentinesHoliday = MonthDay.of( Month.FEBRUARY , 14 );
ZoneId z = ZoneId.of( "America/Edmonton" );
LocalDate today = LocalDate.now( z );
LocalDate valDayThisYear = today.with( valentinesHoliday );
LocalDate nextValDay = valDayThisYear;
if ( valDayThisYear.isBefore( today ) )
{ // If Valentine's day already happened this year, move to next year’s Valentine's Day.
nextValDay = valDayThisYear.plusYears( 1 );
}
ZonedDateTime start = date2002.atStartOfDay( z );
ZonedDateTime stop = nextValDay.atStartOfDay( z );
Duration d = Duration.between( start , stop );
long minutes = d.toMinutes();
System.out.println( "From start: " + start + " to stop: " + stop + " is duration: " + d + " or a total in minutes: " + minutes + "." );
LocalDate date2002 = Year.of( 2002 ).atDay( 1 );
MonthDay valentinesHoliday = MonthDay.of( Month.FEBRUARY , 14 );
ZoneId z = ZoneId.of( "America/Edmonton" );
LocalDate today = LocalDate.now( z );
LocalDate valDayThisYear = today.with( valentinesHoliday );
LocalDate nextValDay = valDayThisYear;
if ( valDayThisYear.isBefore( today ) )
{ // If Valentine's day already happened this year, move to next year’s Valentine's Day.
nextValDay = valDayThisYear.plusYears( 1 );
}
ZonedDateTime start = date2002.atStartOfDay( z );
ZonedDateTime stop = nextValDay.atStartOfDay( z );
Duration d = Duration.between( start , stop );
long minutes = d.toMinutes();
System.out.println( "From start: " + start + " to stop: " + stop + " is duration: " + d + " or a total in minutes: " + minutes + "." );
При запуске.
С начала: 2002-01-01T00: 00-07: 00 [Америка / Эдмонтон] до остановки: 2020-02-14T00: 00-07: 00 [Америка / Эдмонтон]: продолжительность: PT158832H или общее количество минут : 9529920.
О 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?
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval
, YearWeek
, YearQuarter
и more .