Как я могу получить UT C -конвертированную Java метку текущего местного времени? - PullRequest
0 голосов
/ 20 февраля 2020

Может ли кто-нибудь помочь с получением UT C -конвертированной Java временной метки текущего местного времени? Основная цель - получить текущую дату и время, преобразовать их в UT C метку времени и затем сохранить в кэше Ignite как метку времени yyyy-MM-dd hh:mm:ss[.nnnnnnnnn].

Моя попытка была Timestamp.from(Instant.now()). Тем не менее, он все еще учитывает мой местный часовой пояс +03:00. В результате я получаю '2020-02-20 10:57:56' вместо желаемого '2020-02-20 07:57:56'.

Как я могу получить UT C -конвертированную метку времени?

Ответы [ 2 ]

2 голосов
/ 20 февраля 2020

Вы можете сделать это так:

LocalDateTime localDateTime = Instant.now().atOffset(ZoneOffset.UTC).toLocalDateTime();
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
    System.out.println(localDateTime.format(formatter));
1 голос
/ 22 февраля 2020

Не используйте отметку времени

Скорее всего, вам не нужна Timestamp. Это хорошо, потому что класс Timestamp плохо спроектирован, действительно настоящий взлом на вершине и без того плохо спроектированного класса Date. Оба класса также давно устарели. Вместо почти 6 лет go мы получили java .time, современный Java API даты и времени. Начиная с JDB C 4.2 это работает и с вашим драйвером JDB C, а также с вашей современной реализацией JPA.

Используйте OffsetDateTime

Для отметки времени рекомендуемый тип данных в вашей базе данных: timestamp with time zone. В этом случае в Java используйте OffsetDateTime со смещением нуля (то есть UT C). Например:

    OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC);
    System.out.println(now);

    PreparedStatement statement = yourDatabaseConnection
            .prepareStatement("insert into your_table (tswtz) values (?);");
    statement.setObject(1, now);
    int rowsInserted = statement.executeUpdate();

Пример вывода из System.out.println() только сейчас:

2020-02-22T13: 04: 06.320Z

Или используйте LocalDateTime, если ваша временная метка базы данных не имеет часового пояса

Из вашего вопроса у меня сложилось впечатление, что тип данных в вашей базе данных timestamp без часового пояса. Это только второй лучший вариант, но вы можете передать ему LocalDateTime.

    LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);

Остальное - то же, что и раньше. Пример вывода:

2020-02-22T13: 05: 08.776

Если вам нужен старомодный java. sql .Timestamp

Вы просили Timestamp в UT C. A Timestamp - это всегда в UT C. Точнее, это момент времени, независимый от часового пояса, поэтому преобразование его в другой часовой пояс не имеет смысла. Внутренне это реализовано как количество миллисекунд и наносекунд начиная с эпохи. Эпоха определена как первый момент 1970 в UT C.

Класс Timestamp - это запутанный класс. Одна вещь, которая могла бы сбить вас с толку - это когда вы печатаете его, тем самым неявно вызывая его метод toString. Метод toString использует часовой пояс JVM по умолчанию для рендеринга строки, поэтому печатает время в вашем местном часовом поясе. Смешение. Если ваш тип данных в SQL равен timestamp без часового пояса, ваш драйвер JDB C, скорее всего, интерпретирует Timestamp в вашем часовом поясе для преобразования в SQL timestamp. Что в вашем случае неверно, так как ваша база данных использует UT C (рекомендуемая практика). Я могу подумать о трех возможных решениях:

  1. Некоторые механизмы баз данных позволяют вам устанавливать часовой пояс в сеансе. У меня нет никакого опыта с этим сам, это то, что я прочитал; но это может привести к выполнению правильного преобразования из Java Timestamp в SQL timestamp в UT C.
  2. Вы можете сделать неправильное преобразование в Java чтобы компенсировать противоположное неправильное преобразование, выполняемое между Java и SQL. Это хак, а не то, что я хотел бы иметь в своем коде. Я представляю это как последнее средство.

        LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
        Timestamp ts = Timestamp.valueOf(now);
        System.out.println(ts);
    

    2020-02-22 13: 05: 08.776

    Вы замечаете, что это только появляется согласовать с UT C время выше. Это тот же результат, который вы получаете от ответа Випина Шармы, за исключением того, что (1) мой код проще и (2) вы получаете более высокую точность, включая долю секунды.

  3. У вас есть база данных генерировать текущую метку времени в UT C вместо генерации в Java.

Ссылки

...