Ответ от deHaar , как правило, является правильным и разумно использует современные java.time классы.Однако я бы использовал немного другой подход.
tl; dr
OffsetDateTime.of( // Represent a moment as a date, a time-of-day, and an offset-from-UTC.
LocalDate.now( ZoneOffset.UTC ) , // Current date as seen right now in UTC. Beware: For any given moment, the date varies around the globe by zone.
LocalTime.parse( "12:15:00" ) , // Your specified time-of-day.
ZoneOffset.UTC // An offset of zero hours-minutes-seconds, for UTC itself.
) // Returns an `OffsetDateTime` object.
.atZoneSameInstant( // Adjust from UTC to a time zone. Same moment, different wall-clock-time.
ZoneId.of( "America/Port_of_Spain" ) ; // One of the many time zones that are behind UTC by four hours on that date.
) // Returns a `ZonedDateTime` object.
.toLocalTime() // Extract the time-of-day only, leaving behind the date and the zone.
Часовой пояс
Мой часовой пояс GMT-4
Нет.Это не часовой пояс.
Значение GMT-4
представляет просто смещение от UTC .Количество часов-минут-секунд вперед или позади базовой линии UTC.
Часовой пояс намного больше.Часовой пояс имеет имя и представляет историю прошлых, настоящих и будущих изменений смещения, используемых людьми определенного региона.Поэтому часовой пояс всегда предпочтительнее простого смещения.
Укажите правильное имя часового пояса в формате Continent/Region
, например America/Montreal
, Africa/Casablanca
илиPacific/Auckland
.Никогда не используйте 2-4 буквенные сокращения, такие как EST
или IST
, так как они не истинные часовые пояса, не стандартизированы и даже не уникальны (!).
ZoneId z = ZoneId.of( "Africa/Casablanca" ) ;
Если ваш часовой пояс в настоящее время отстает на четыре часа от UTC, вы должны быть в таком часовом поясе, как America/Aruba
, America/Puerto_Rico
, America/Manaus
, America/Martinique
и т. Д.
ZoneId z = ZoneId.of( "America/Martinique" ) ;
UTC
У меня есть строка UTC с форматом (ЧЧ: мм: сс)
Нет.
Такое значение, как "12:15:00"
, нельзя назвать значением в UTC.Без даты это значение не имеет реального значения.Момент состоит из трех частей:
- дата,
- время суток и
- смещение / зона.
Говоря «полдень в UTC», мы получаем только 2 из 3 частей.Дата отсутствует.
Сегодня… что за концепция
Возможно, вы хотите применить это время дня к текущей дате, как видно по UTC.
LocalDate todayUTC = LocalDate.now( ZoneOffset.UTC ) ;
Просто имейте в виду, что в любой данный момент дата меняется по всему земному шару в зависимости от зоны .В этот самый момент дата «завтра» в Токио, Япония, и «вчера» в Толедо, штат Огайо, США.
OffsetDateTime
Объедините все три в объект OffsetDateTime
: дату, время суток и смещение / зону.
LocalTime localTime = LocalTime.parse( "12:15:00" ) ;
OffsetDateTime odt = OffsetDateTime.of( todayUTC , localTime, ZoneOffset.UTC ) ;
ZonedDateTime
Настройка от UTC до вашего конкретного часового пояса.Тот же самый момент, та же самая одновременная точка на временной шкале, другое время настенных часов.Примените ZoneId
, чтобы получить объект ZonedDateTime
.Часовой пояс показывает, когда и когда Летнее время (DST) применяется к этой конкретной зоне, и корректируется соответствующим образом.
ZoneId z = ZoneId.of( "America/Martinique" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
Неправильный подход
Вы не должныдобавление / вычитание некоторого количества часов из LocalTime
.В некоторые даты в некоторых зонах конкретное время суток может не существовать.Например, для перехода на летнее время в день «весна-вперед» в Соединенных Штатах время в 02:15:00 не существует, поскольку часы отскакивают вперед с 02:00:00.до 03:00:00
Правильный подход с использованием класса ZonedDateTime
автоматически изменится соответствующим образом.