Преобразование времени UTC ЧЧ: мм: сс в Время устройства ЧЧ: мм: сс и добавление перехода на летнее время, если доступно - PullRequest
0 голосов
/ 24 сентября 2019

У меня есть строка UTC в формате (ЧЧ: мм: сс), и мне нужно преобразовать значение строки в время устройства в том же формате (ЧЧ: мм: сс), а также добавить время сохранения дня, если оно доступно. Я пробовалпреобразовать строку UTC во время устройства по этому коду, но я получаю задержку в 1 час из-за (дневного времени).

String utcTimeString = "12:15:00"
SimpleDateFormat formatter = new SimpleDateFormat("HH: mm: ss");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
Date value = formatter.parse(utcTimeString);

SimpleDateFormat dateFormatter = new SimpleDateFormat("HH: mm: ss"); 
dateFormatter.setTimeZone(TimeZone.getDefault());
utcDateString = dateFormatter.format(value);

Мой часовой пояс GMT-4

ОжидаетсяВыход: 08:15:00;Дано: 07: 15: 00;

Ответы [ 2 ]

1 голос
/ 25 сентября 2019

Ответ от 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 автоматически изменится соответствующим образом.

0 голосов
/ 24 сентября 2019

Вы можете использовать java.time, современный API даты и времени, и анализировать время String до определенного момента времени, то есть Instant.
Затем использовать ZonedDateTime объекты, чтобы применить определенное время.Зона, что может быть сделано по-разному, я покажу вам один из них здесь:

public static void main(String[] args) {
    // the source is just a time, but to correctly convert it, you need a date
    String utcTime = "12:15:00";
    // take today's date
    LocalDate today = LocalDate.now();
    // create a parseable date time String
    String parseableDateTime = today.format(DateTimeFormatter.ISO_DATE) + "T" + utcTime + "Z";
    // then create an Instant parsing the date time String
    Instant instant = Instant.parse(parseableDateTime);

    // get the ZoneId of UTC in order to have the time in UTC
    ZoneId utc = ZoneId.of("UTC");
    // do the same with your ZoneOffset of -4 Hours
    ZoneId gmtMinusFour = ZoneId.ofOffset("GMT", ZoneOffset.ofHours(-4));

    // create a UTC ZonedDateTime of the instant and the UTC ZoneID 
    ZonedDateTime utcZdt = ZonedDateTime.ofInstant(instant, utc);
    // then use that ZonedDateTime to convert it to a time with your ZoneId
    ZonedDateTime gmtMinusFourZdt = utcZdt.withZoneSameInstant(gmtMinusFour);

    // finally print both ZonedDateTimes in order to compare them
    System.out.println("UTC time is:\t\t" 
            + utcZdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
    System.out.println("GMT-4 time is:\t\t"
            + gmtMinusFourZdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));

    // then just get the time part of the converted ZonedDateTime
    LocalTime localTime = gmtMinusFourZdt.toLocalTime();
    // and print it
    System.out.println("Converted time is:\t" 
            + localTime.format(DateTimeFormatter.ISO_TIME));
}

Вывод:

UTC time is:        2019-09-24T12:15:00Z[UTC]
GMT-4 time is:      2019-09-24T08:15:00-04:00[GMT-04:00]
Converted time is:  08:15:00

Могут быть и лучшие решения, но я надеюсь, что это поможет в любом случае...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...