tl; dr
... проанализировано ... из строки ... часовой пояс не указан ... Я хочу установить определенный часовой пояс
LocalDateTime.parse( "2018-01-23T01:23:45.123456789" ) // Parse string, lacking an offset-from-UTC and lacking a time zone, as a `LocalDateTime`.
.atZone( ZoneId.of( "Africa/Tunis" ) ) // Assign the time zone for which you are certain this date-time was intended. Instantiates a `ZonedDateTime` object.
Нет времениЗона в juDate
Как указано в других правильных ответах, java.util.Date не имеет часового пояса † .Он представляет UTC / GMT (без смещения часового пояса).Очень запутанно, потому что его метод toString
применяет часовой пояс JVM по умолчанию при генерации строкового представления.
Избегайте juDate
По этой и многим другим причинам вам следует избегать использования встроенного java.util.Date & .Calendar & java.text.SimpleDateFormat.Они общеизвестно хлопотно.
Вместо этого используйте java.time пакет в комплекте с Java 8 .
java.time
Классы java.time могут представлять момент на временной шкале тремя способами:
- UTC (
Instant
) - со смещением (
OffsetDateTime
с ZoneOffset
) - с часовым поясом (
ZonedDateTime
с ZoneId
)
Instant
В java.time , базовым строительным блоком является Instant
, момент на временной шкале в UTC.Используйте Instant
объекты для большей части вашей бизнес-логики.
Instant instant = Instant.now();
OffsetDateTime
Примените offset-from-UTC , чтобы приспособиться к * 1061 некоторой местности* настенные часы .
Применить ZoneOffset
, чтобы получить OffsetDateTime
.
ZoneOffset zoneOffset = ZoneOffset.of( "-04:00" );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );
ZonedDateTime
Лучшеприменить часовой пояс , смещение плюс правила обработки аномалий, такие как Летнее время (DST) .
Примените ZoneId
к Instant
, чтобы получить ZonedDateTime
.Всегда указывайте правильное имя часового пояса .Никогда не используйте 3-4 сокращения, такие как EST
или IST
, которые не являются ни уникальными, ни стандартизированными.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
LocalDateTime
Если во входной строке отсутствовал какой-либо индикатор смещения илизона, анализируется как LocalDateTime
.
Если вы уверены в предполагаемом часовом поясе, присвойте ZoneId
, чтобы получить ZonedDateTime
.См. Пример кода выше в разделе tl; dr вверху.
Форматированные строки
Вызовите метод toString
в любом из этих трех классов, чтобы сгенерировать строку, представляющуюзначение даты и времени в стандартном формате ISO 8601 .Класс ZonedDateTime
расширяет стандартный формат, добавляя имя часового пояса в скобках.
String outputInstant = instant.toString(); // Ex: 2011-12-03T10:15:30Z
String outputOdt = odt.toString(); // Ex: 2007-12-03T10:15:30+01:00
String outputZdt = zdt.toString(); // Ex: 2007-12-03T10:15:30+01:00[Europe/Paris]
Для других форматов используйте класс DateTimeFormatter
.Обычно лучше, чтобы этот класс генерировал локализованные форматы, используя ожидаемый пользовательский язык и культурные нормы.Или вы можете указать конкретный формат.
О 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 .
Joda-Time
Хотя Joda-Time все еще активно поддерживается, его создатели сказали нам перейти на java.time, как только это будет удобно.Я оставляю этот раздел нетронутым для справки, но вместо этого предлагаю использовать раздел java.time
.
В Joda-Time , объект даты-времени (DateTime
) действительно знает свой назначенный часовой пояс.Это означает смещение от UTC и правил и истории летнего времени (DST) этого часового пояса и других подобных аномалий.
String input = "2014-01-02T03:04:05";
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeIndia = new DateTime( input, timeZone );
DateTime dateTimeUtcGmt = dateTimeIndia.withZone( DateTimeZone.UTC );
Вызовите метод toString
для генерацииСтрока в формате ISO 8601 .
String output = dateTimeIndia.toString();
Joda-Time также предлагает широкие возможности для генерации всех видов других форматов строк.
При необходимости вы можете преобразовать изJoda-Time DateTime для java.util.Date.
Java.util.Date date = dateTimeIndia.toDate();
Поиск StackOverflow по "joda date", чтобы найти еще много примеров, некоторые довольно подробные.
† На самом деле - это часовой пояс, встроенный в java.util.Date, используемый для некоторых внутренних функций (см. Комментарии к этому ответу).Но этот внутренний часовой пояс не отображается как свойство и не может быть установлен.Этот внутренний часовой пояс не тот, который используется методом toString
при создании строкового представления значения даты и времени;вместо этого текущий часовой пояс JVM по умолчанию применяется на лету.Таким образом, как сокращение, мы часто говорим: «У juDate нет часового пояса».Смешение?Да.Еще одна причина избегать этих усталых старых классов.