Этот вопрос и ответы теперь устарели. Они используют старые классы даты и времени, устаревшие с помощью инфраструктуры java.time, встроенной в Java 8 и более поздние версии. Старые классы плохо спроектированы, запутаны и хлопотны; Избегайте их .
Избегайте 3-4 буквенных кодов зоны
Избегайте 3-4-буквенных кодов, таких как BST
. Они не стандартизированы и не уникальны. Они на самом деле не представляют часовые пояса. И они добавляют еще больше путаницы к проблеме перехода на летнее время (DST).
Вместо этого используйте надлежащие часовые пояса . Большинство форматов continent/region
, например Europe/London
.
Избегайте установки часового пояса по умолчанию
Звонить java.util.TimeZone.setDefault
следует только в самых крайних случаях. Этот вызов влияет на весь код, работающий во всех потоках всех приложений в JVM, немедленно во время времени выполнения.
Вместо этого во всем вашем коде даты и времени укажите желаемый / ожидаемый часовой пояс. Если опущено, Java отступает, неявно полагаясь на текущий часовой пояс JVM по умолчанию. Как отмечено выше, это значение по умолчанию может измениться в любой момент во время выполнения! Вместо этого укажите явно. Если вы обычно указываете желаемый / ожидаемый часовой пояс в качестве переданного аргумента, то текущий часовой пояс по умолчанию является спорным, не имеет значения.
java.time
Среда java.time встроена в Java 8 и более поздние версии. См. Учебник . Определено JSR 310. Вдохновлено очень успешной библиотекой Joda-Time.
Instant
Instant
- это момент времени на UTC.
В следующем примере показано, как классы java.time могут анализировать / генерировать строки по умолчанию в стандартном формате ISO 8601 без указания шаблона разбора. Используйте класс DateTimeFormatter
для указания других нестандартных шаблонов.
Instant instant = Instant.parse( "2011-12-27T09:00:00Z" );
ZonedDateTime
Примените часовой пояс по необходимости, получив ZonedDateTime
.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );
Генерация строк
Вы можете создавать текстовые представления объекта ZonedDateTime, используя DateTimeFormatter
. Вы можете указать пользовательские шаблоны. Или, как я рекомендую, пусть java.time локализуется для вас.
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM );
Лучше всего указать желаемый / ожидаемый Locale
по той же причине, что и часовой пояс… Текущее значение по умолчанию JVM может быть изменено в любой момент с помощью любого кода в любом потоке любого приложения, работающего в JVM , Locale
определяет (а) человеческий язык, используемый для названий дня и месяца, и (б) культурные нормы, такие как запятые по сравнению с периодами, и порядок частей, таких как месяц или день или год, который идет первым.
formatter = formatter.withLocale( Locale.CANADA_FRENCH );
String output = zdt.format( formatter );
О 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
и еще .