Не используйте отметку времени
Скорее всего, вам не нужна 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 (рекомендуемая практика). Я могу подумать о трех возможных решениях:
- Некоторые механизмы баз данных позволяют вам устанавливать часовой пояс в сеансе. У меня нет никакого опыта с этим сам, это то, что я прочитал; но это может привести к выполнению правильного преобразования из Java
Timestamp
в SQL timestamp
в UT C. Вы можете сделать неправильное преобразование в 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) вы получаете более высокую точность, включая долю секунды.
- У вас есть база данных генерировать текущую метку времени в UT C вместо генерации в Java.
Ссылки