Как преобразовать метку времени Unix в миллисекундах в метку времени, совместимую с PostgreSQL?

У меня есть служба REST с конечной точкой, которая ПОЛУЧАЕТ данные в течение запрошенного интервала. Запрошенный интервал отображается как две временные метки Unix в миллисекундах типа Long. Нравится:

Long start = 1622648253010;
Long end = 1622651853010;

У меня есть база данных PostgreSQL, в которой есть таблица со столбцом Timestamp. Мне нужно выбрать некоторые данные из этой таблицы, где отметка времени находится между двумя отметками времени Unix. Однако PostgreSQL не понимает отметки времени Unix, поэтому мне нужно преобразовать две отметки времени в отметки времени, совместимые с PostgreSQL, прежде чем использовать их в запросе. Преобразование должно выполняться на Java, а не в SQL-запросе.

Как я могу это сделать? Я знаю только один способ:

java.sql.Timestamp.from(Instant.ofEpochSecond(
                        start.getSeconds(), start.getNanos()))

Но это не работает.


person Ben    schedule 02.06.2021    source источник
comment
Я рекомендую вам не использовать java.sql.Timestamp. Этот класс очень плохо спроектирован и давно устарел. Вместо этого используйте OffsetDateTime или LocalDateTime; оба взяты из java.time, современного API даты и времени Java.   -  person Ole V.V.    schedule 02.06.2021
comment
1622648253010 не является timestamp значением blog.sql-workbench.eu/post/epoch-mania   -  person a_horse_with_no_name    schedule 02.06.2021


Ответы (3)


java.time

java.util API даты и времени и их API форматирования SimpleDateFormat устарели и подвержены ошибкам. Рекомендуется полностью отказаться от них и перейти на современный API даты и времени *.

  1. Преобразуйте миллисекунды эпохи в OffsetDateTime:
long millisStart = 1622648253010L;
OffsetDateTime odtStart = Instant.ofEpochMilli(millisStart).atOffset(ZoneOffset.UTC);
  1. Используйте OffsetDateTime с PreparedStatement:
PreparedStatement st = conn.prepareStatement(SELECT * FROM mytable WHERE columnfoo BETWEEN ? AND ?");
st.setObject(1, odtStart);
st.setObject(2, odtEnd);
ResultSet rs = st.executeQuery(); 
while (rs.next()) {
   //...
}
rs.close();
st.close();

Узнайте больше о java.time, современном API даты и времени * из След: Дата Время.


* По любой причине, если вам нужно придерживаться Java 6 или Java 7, вы можете использовать ThreeTen-Backport, который поддерживает большую часть функций java.time для Java 6 и 7. Если вы работаете над проектом Android и ваш уровень API Android по-прежнему не соответствует Java-8, проверьте API Java 8+ доступно через удаление сахара и Как использовать ThreeTenABP в Android Project.

person Arvind Kumar Avinash    schedule 02.06.2021

Разделите на 1000 и используйте to_timestamp)

select to_timestamp(1622648253010/1000);
      to_timestamp      
------------------------
 2021-06-02 17:37:33+02
person Dri372    schedule 02.06.2021

Тип Long не имеет методов getSeconds() и getNanos(). См .: https://docs.oracle.com/javase/7/docs/api/java/sql/Timestamp.html#Timestamp%28long%29

person markw    schedule 02.06.2021