Как преобразовать длинную локальную метку времени в метку времени String UTC

Этот вопрос довольно близок к моему, однако я считаю, что ответ мне не подходит. У меня есть метка времени Long.

ts = 1362156863140L

Поскольку он длинный, я считаю его наивной временной меткой часового пояса, верно? Это отметка времени по местному времени в Кельне - UTC + 0200 (CET). Поэтому, когда я конвертирую его в метку времени с учетом часового пояса String, я хочу получить:

2013-03-01T14:54:23.140Z

или же

2013-03-01T16:54:23.140+02:00

Я использую решение из ответа в начале своего вопроса:

Instant.ofEpochMilli(timestamp).atOffset(ZoneOffset.of("+2"));

который возвращает:

2013-03-01T18:54:23.140+02:00

другой часовой пояс:

Instant.ofEpochMilli(timestamp).atOffset(ZoneOffset.of("Z"));

возвращает:

2013-03-01T16:54:23.140Z

Таким образом, эти методы на самом деле не изменяют часовой пояс, они просто изменяют представление временной метки. Я также попробовал другой метод:

OffsetDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.of("UTC"));

Но результаты точно такие же. Это решения был полезен, но оригинальный подход:

int offset = TimeZone.getTimeZone("Europe/Amsterdam").getRawOffset();
long newTime = timestamp - offset;

не считает летнее / зимнее время. И предлагаемые ответы используют класс Calendar, который устарел для JDK8. Что работает и достаточно очевидно:

OffsetDateTime.ofInstant(Instant.ofEpochMilli(Timestamp), ZoneId.of("UTC")).minusSeconds(7200);

Но это определенно неправильный способ сделать это, так как я могу сделать это с часовым поясом?

Ваш вопрос слишком общий? Скажите нам, что именно вам нужно?

Ravindra Ranwala 29.05.2018 14:32

Как преобразовать этот 1362156863140L в этот 2013-03-01T14: 54: 23.140Z

Charlie4fun 29.05.2018 14:34

«Поскольку это долго, я считаю это наивной временной меткой часового пояса». Я бы сказал наоборот. Учитывая, что long не может (легко) содержать информацию о часовом поясе, его нельзя хранить таким образом. Длинная метка времени должна быть моментом времени независимо от часового пояса (то есть метка времени Unix).

Michael 29.05.2018 14:41

Это то, что я получаю для вашего значения метки времени ввода. 2013-03-01T21:24:23.140

Ravindra Ranwala 29.05.2018 14:55

Либо ваши предположения неверны, либо неверна ваша длинная ценность. Длинное значение, подобное вашему, обычно обозначает количество миллисекунд с эпохи 1 января 1970 года, 00:00 UTC. При таком понимании ваше длинное значение обозначает 2013-03-01T16:54:23.140Z, а не 2013-03-01T14:54:23.140Z (Z означает UTC). Если кто-то дал вам длинную ценность и имел в виду последнее, он сделал что-то нестандартным образом, что обязательно вызовет путаницу. А если так, то я не знаю, как бы они отнеслись к летнему времени, поэтому я также не могу сказать вам, как вы должны справиться с этим.

Ole V.V. 29.05.2018 20:35
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
5
379
1

Ответы 1

Я полагаю, что метка времени находится в UTC, и вам нужно изменить метку времени на CET. Взгляните на метод withZoneSameInstant(), может быть полезным.

    long timeStamp = 1362156863140L;
    ZoneId sourceZone = ZoneId.of("UTC");
    ZoneId targetZone = ZoneId.of("CET");
    String s = ZonedDateTime.ofInstant(Instant.ofEpochMilli(timeStamp), sourceZone)
            .withZoneSameLocal(targetZone)
            .toString();
    System.out.println(s);

Наконец-то я использовал это: Instant.ofEpochMilli(timestamp).atOffset(ZoneOffset.of("Z"))‌​.withOffsetSameLocal‌​(ZoneOffset.of("+2")‌​);, но я до сих пор не знаю, как вести себя в летнее время.

Charlie4fun 29.05.2018 17:42

Не полагайтесь на трехбуквенные сокращения часовых поясов, они не стандартизированы и не уникальны. На время в Кельне / Кельне я предлагаю ZoneId.of("Europe/Berlin"). Ваш код отражает хорошее предположение о том, как интерпретировать длинное значение спрашивающего, но мы не можем быть уверены в этом.

Ole V.V. 29.05.2018 20:38

@ Charlie4fun ZonedDateTime обрабатывает летнее / зимнее время автоматически, насколько я знаю, но вам следует использовать ZoneId, а не смещения вроде "+2"

jahra 29.05.2018 20:40

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