Преобразование времени utc согласно смещению в java 8

Я получаю время и смещение в строке.

Время указано в формате UTC, и мне нужно преобразовать это время в соответствии с смещением, а затем назначить его объекту Calendar.

Проблема в том, что я использую метод plusHours() класса OffsetDateTime. Я получаю такие же результаты.

OffsetDateTime odtB = OffsetDateTime.parse( "2018-03-26T06:00:00Z" ) ;
odtB.plusHours(2);
System.out.println(odtB); 

Например, если моя дата - "2018-03-26T06:00:00Z", а значение смещения / часового пояса - «+02: 00», как изменить его для получения выходного "2018-03-26T08:00:00Z"?

Вы, кажется, запутались. О каком входе вы говорите? Ввод времени без информации о смещении или с, например, «2019-01-16T00: 05: 00.000» по сравнению с «2019-01-16T00: 05: 00.000Z» или «2019-01-16T00: 05: 00.000 + 00: 00»? Если у вашего ввода времени уже есть информация о смещении, то нет необходимости объединять ее с какой-либо дополнительной информацией о смещении, потому что вы можете напрямую интерпретировать ее как мгновенную и перевести / перенести ее на старый объект java.util.Date.

Meno Hochschild 11.04.2018 13:04
2018-03-26T08:00:00Z на два часа позже по Гринвичу (Z означает UTC). Это то, что вы хотите? Или, скорее, 2018-03-26T08:00:00+02:00, то есть исходный момент времени с часами настенных часов вашего смещения?
Ole V.V. 11.04.2018 16:33
0
3
4 022
3

Ответы 3

Пытаться

OffsetDateTime odtB = OffsetDateTime.parse( "2019-01-16T00:05:00.000" ) ;
odtB = odtB.plusHours(2);
System.out.println(odtB);

Привет, Марек, спасибо, все работает. Это правильный подход для работы со значениями смещения или есть другой способ изменить время в соответствии с смещением.

user2142786 11.04.2018 12:59

предположим, если часовой пояс +5:30, как с этим бороться.

user2142786 11.04.2018 13:02

Я предполагаю, что вам нужно вместо этого использовать ToLocalTime, если у вас есть UTC в качестве источника: msdn.microsoft.com/en-us/library/…

Mareks Zirdzins 11.04.2018 13:08

Как стоит код, выкидывает java.time.format.DateTimeParseException: Text '2019-01-16T00:05:00.000' could not be parsed at index 23. Со строкой из вопроса, который он запускает, но дает неправильный результат, 2018-03-26T08:00Z, который находится в UTC (обозначен Z в конце), что, как я понял, не было тем, о чем просили. И ваша ссылка на документацию .NET вряд ли актуальна.

Ole V.V. 11.04.2018 17:53

Извините, только что прочитал в заголовке, что у вас был пример Java. Слишком много ответов переполнения в день :). Я полагаю, ты получил свой ответ в конце дня, верно?

Mareks Zirdzins 12.04.2018 12:04

Перво-наперво: метод plusHours возвращает ДругойOffsetDateTime, но не меняет исходный. Чтобы получить результат работы метода, нужно присвоить его переменной:

OffsetDateTime odtB = OffsetDateTime.parse("2018-03-26T06:00:00Z");
odtB = odtB.plusHours(2);
System.out.println(odtB);

Это напечатает:

2018-03-26T08:00Z

Теперь к вашему вопросу:

For example if my date is "2018-03-26T06:00:00Z" and offset/Timezone value is "+02:00" how to change it for getting output "2018-03-26T08:00:00Z"?

Я думаю, вы ошибаетесь в некоторых концепциях. В конце концов, Z - это Указатель UTC, и это то же самое, что и +00:00.

Обе даты, указанные выше (2018-03-26T06:00:00Z и 2018-03-26T08:00Z), указаны в формате UTC, и каждая представляет собой момент разные (разные точки на временной шкале). Когда вы вызываете plusHours(2), результатом становится еще один OffsetDateTime, который на 2 часа позже первого.

Если вы хотите перерабатыватьOffsetDateTime с другим смещением, вам не следует добавлять к нему часы. Вам следует сделать это:

OffsetDateTime odtB = OffsetDateTime.parse("2018-03-26T06:00:00Z");
// convert to offset +02:00
odtB = odtB.withOffsetSameInstant(ZoneOffset.ofHours(2));

Теперь результат - 2018-03-26T08:00+02:00 - обратите внимание, что смещение изменилось с Z на +02: 00, но оба (2018-03-26T08:00+02:00 и 2018-03-26T06:00:00Z) представляют в то же мгновение (одна и та же точка на временной шкале).

Это станет яснее, если вы сравните результаты с помощью isEqual (метод проверяет, соответствуют ли даты одному и тому же моменту):

OffsetDateTime odtB = OffsetDateTime.parse("2018-03-26T06:00:00Z");

// add hours
OffsetDateTime twoHoursLater = odtB.plusHours(2);
System.out.println(odtB.isEqual(twoHoursLater)); // false

// convert to offset +02:00
OffsetDateTime sameInstantDifferentOffset = odtB.withOffsetSameInstant(ZoneOffset.ofHours(2));
System.out.println(odtB.isEqual(sameInstantDifferentOffset)); // true

Чтобы преобразовать в другие смещения, такие как +05:30, вам просто нужно изменить используемое смещение. Вместо ZoneOffset.ofHours(2) можно использовать один из них:

ZoneOffset.ofHoursMinutes(5, 30)
ZoneOffset.of("+05:30")

Насколько я понимаю, вы хотите преобразовать дату и время в своей строке - здесь 26 марта в 6 утра - в тот же момент времени в вашем местном часовом поясе в UTC + 2, то есть в 8 утра (а не в UTC). Вы действительно делаете это неправильно. Вместо этого сделайте:

    ZoneOffset myOffset = ZoneOffset.ofHours(2);
    odtB = odtB.withOffsetSameInstant(myOffset);
    System.out.println(odtB);

Выход:

2018-03-26T08:00+02:00

Еще лучше, чем полагаться на смещение, использовать реальный часовой пояс, например:

    ZoneId myZone = ZoneId.of("Africa/Kigali");
    ZonedDateTime zdt = odtB.atZoneSameInstant(myZone);
    System.out.println(zdt);

2018-03-26T08:00+02:00[Africa/Kigali]

Если вам нужен OffsetDateTime, я все же рекомендую конвертировать через соответствующий ZoneId, как указано выше, а затем просто конвертировать обратно в OffsetDateTime:

    odtB = zdt.toOffsetDateTime();
    System.out.println(odtB);

2018-03-26T08:00+02:00

Однако вы сказали, что должны назначить его Calendar. Самый простой и правильный способ сделать это - также через ZonedDateTime:

    Calendar cal = GregorianCalendar.from(zdt);

Как я надеюсь, вы знали, что класс Calendar давно устарел. Тем не менее, возможно, вам понадобится объект Calendar для устаревшего API, который вы не можете изменить или просто не хотите менять прямо сейчас.

Если вам нужно другое смещение, вы просто создаете мощь:

    ZoneOffset myOffset = ZoneOffset.ofHoursMinutes(5, 30);

Однако я все же рекомендую вам использовать правильный часовой пояс, например:

    ZoneId myZone = ZoneId.of("Asia/Kolkata");

Что пошло не так в вашем коде?

Я подозреваю, что у вас две ошибки:

  • Если добавить 2 часа к вашему OffsetDateTime в UTC, вы получите на два часа позже по UTC. Я так понимаю, вы не хотели ни два часа спустя, ни время по всемирному координированному времени.
  • Как уже говорили другие, plusHours возвращает новыйOffsetDateTime с новым значением. Кажется, вы игнорируете возвращаемое значение, фактически отбрасывая результат. Метод должен вернуть новый объект, потому что OffsetDateTime неизменяем.

РЕДАКТИРОВАТЬ: Сначала я не читал ваш вопрос должным образом, и он не очень ясен. Я изменил ответ, и теперь он отвечает тому, что, как я думаю, вы имеете в виду.

Другие вопросы по теме