powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / JDBC (Postgres) & java.time.ZonedDateTime
24 сообщений из 24, страница 1 из 1
JDBC (Postgres) & java.time.ZonedDateTime
    #39116271
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Столкнулся с бизнес задачей, где нам важен часовой пояс при дате. Можно, конечно, обойтись и без часового пояса, но это будет _жутко_ _коряво_ и не удобно.

В БД есть тип "timestamp with timezone", в Java 1.8 есть java,time.ZonedDateTime

Как записать java.time.ZonedDateTime в БД я разобрался, но как его прочитать? Декомпилировал классы от JDBC PostgreSQL и никаких методов кроме getTimestamp не нашел. Т.ч. риторический вопрос: Неужели все так плохо и Java такое г...?

Пока решил хранить все данные в виде даты + текст в ISO формате. При записи в БД пишу в два поля, при чтении из БД использую поле текст в ISO формате. Но как-то это кривовато выглядит.
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39116333
Alexander A. Sak
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Конечно джава - г...
Можно пример того, что требуется, на не-г...? Я, честно говоря, не совсем понял задачу. Обычно даты без таймзоны не бывает. Если и бывает, то на самом деле неявно используется какая-то одна: UTC, локальная или еще какая-то фиксированная.
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39116347
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev,

ResultSet.getDate() не работает разве?
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39116363
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39116543
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczResultSet.getDate() не работает разве?

Там есть TimeZone ?

Мне нужно Date + TimeZone как оно было в ОРИГИНАЛЕ. Единственный класс, который вроде такое позволяет хранить без извращений, java.time.ZonedDateTime. При записи в БД, я могу "разделить" его на Timestamp (или DateTime) + Calendar и соответственно записать в БД (сохранив Timezone)

getDate, AFAIK (могу ошибаться) возвращает мне дату с текущей/системной TimeZone/Calendar или позволяет указать TimeZone/Calendar который я "хочу" использовать. Но мне нужна та TimeZone/Calendar которая сохранена в БД.

Беда в том, что не понятно, можно ли сохраненный TimeZone считать обратно. Точнее, понимаю, что ответ нет.

Это действительно настолько редкая потребность/желание хранить и обрабатывать даты ВМЕСТЕ с TimeZone с которыми они пришли? В БД поля такого типа есть (timestamp with timezone), а JDBC получается их обрабатывать вообще не умеет (((


Если говорить о PostgreSQL, то текущее драйвера () вроде (???) читают все даты через класс org.postgresql.jdbc2.TimestampUtils, через ниже приведенный код. Где видно, что если параметр TimeZone не указан, то он берется не из БД, как бы хотелось, а просто getDefaultTz() - что IMHO есть полное У.Г.:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
    public Date convertToDate(long millis, TimeZone tz)
    {
        if(millis <= 0x8000000001556d80L || millis >= 0x7ffffffffe3cb580L)
            return new Date(millis);
        if(tz == null)
            tz = getDefaultTz();
        if(isSimpleTimeZone(tz.getID()))
        {
            int offset = tz.getRawOffset();
            millis += offset;
            millis = (millis / 0x5265c00L) * 0x5265c00L;
            millis -= offset;
            return new Date(millis);
        } else
        {
            Calendar cal = calendarWithUserTz;
            cal.setTimeZone(tz);
            cal.setTimeInMillis(millis);
            cal.set(11, 0);
            cal.set(12, 0);
            cal.set(13, 0);
            cal.set(14, 0);
            return new Date(cal.getTimeInMillis());
        }
    }





Если говорить о PostgreSQL, то даже PgAdmin мне сохраненные данные показывает приведенные к моей TimeZone (MSK +3), но в БД данные правильные (смотрел дампом команды copy) (((.
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39116555
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Leonid Kudryavtsev,
postgre sql не хранит сведения о таймзоне, тип timestamp with timezone влияет только на работу с литералами.
В самой же базе всё хранится в utc (можно сказать, абсолютное значение времени), поэтому, если в java работа с базой реализована правильно, то все равно, какой timestamp в поле.
Вам же надо получить не значение времени, а его местное представление, для чего служит объект java.util.Calendar.
Код: java
1.
2.
3.
4.
Calendar cln;
cln = Calendar.getInstance().setTime(resultset.getTimestamp()); // на клиенте
// или
cln = new GregorianCalendar(timezone).setTime(resultset.getTimestamp()); // на сервере


еще есть такой вариант
Код: java
1.
cln = Calendar.getInstance(timezone).setTime(resultset.getTimestamp());

, но это, по большому счету, неправильно, хотя результат будет аналогичен приведенному выше варианту для сервера
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39116573
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanrapostgre sql не хранит сведения о таймзоне, тип timestamp with timezone влияет только на работу с литералами.

Неправда ваша. Достаточно сделать дамп таблицы через COPY, что бы увидит, что все замечательно сохраняется.


ivanraа его местное представление, для чего служит объект java.util.Calendar.


Я хочу его местное представление, в том виде, как оно БЫЛО у пользователя в момент сохранения в БД. Пользователь за время между сохранением и просмотром мог уже 100 раз успеть в другую точку мира перелететь. Мне же хочется, время хранить в том виде "как было".

Пока, наверное, придется хранить в тексте. Т.к. работа с новым (с 1.8) типом java.time.ZonedDateTime в java.sql похоже пока не поддерживает (((. Чуть меньше, чем полностью ((( Что лично меня расстроило (((
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39116631
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev,
там ссылка была.
Тайм зона зависит от сессии. И работают совместно не только при записи, но и при чтении
alter session set time_zone
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39116642
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Postgre SQL не хранит и не умеет извлекать исходную таймзону из timestamp поля. Всё зависит от настроек сервера/сессии. Так что в любом случае, надо либо сохранять локальное время, либо таймзону в виде строки, в отдельное поле
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39116661
Alexander A. Sak
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsevivanrapostgre sql не хранит сведения о таймзоне, тип timestamp with timezone влияет только на работу с литералами.

Неправда ваша. Достаточно сделать дамп таблицы через COPY, что бы увидит, что все замечательно сохраняется.


ivanraа его местное представление, для чего служит объект java.util.Calendar.


Я хочу его местное представление, в том виде, как оно БЫЛО у пользователя в момент сохранения в БД. Пользователь за время между сохранением и просмотром мог уже 100 раз успеть в другую точку мира перелететь. Мне же хочется, время хранить в том виде "как было".

Пока, наверное, придется хранить в тексте. Т.к. работа с новым (с 1.8) типом java.time.ZonedDateTime в java.sql похоже пока не поддерживает (((. Чуть меньше, чем полностью ((( Что лично меня расстроило (((

Какой версией PG пользуетесь? У меня 9.3.10

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
postgres=# create table www (tz timestamp with time zone);
CREATE TABLE
postgres=# insert into www values(current_timestamp);
INSERT 0 1
postgres=# set timezone TO 'UTC';
SET
postgres=# insert into www values(current_timestamp);
INSERT 0 1
postgres=# copy www to stdout;
2015-11-30 15:21:09.001305+00
2015-11-30 15:21:21.656228+00
postgres=# set timezone TO 'Asia/Omsk';
SET
postgres=# copy www to stdout;
2015-11-30 21:21:09.001305+06
2015-11-30 21:21:21.656228+06
postgres=# 


Что-то не замечаю, что "замечательно сохраняется".
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39116745
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexander A. SakЧто-то не замечаю, что "замечательно сохраняется".
Да, не прав ((( не туда посмотрел. Извиняюсь.

Значит вообще в жизни счастья нет (((
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39116749
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexander A. Sak,

Спасибо. По крайне мере не буду городить в БД падеж типов, а тупо все в timestamp (для возможно последующей сортировки) + копия в text. Раз что timestamp, что timestamp with timezone одно и то же (((
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39116771
Nebo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39116948
pavel_nv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev,

Так может быть проще сделать что пользователь указывает свою тайм зону у себя в настройках? Ведь если пользователь перелетел в другой часовой пояс и он хочет видеть время в старом поясе, то и вводить время лучше в этом же поясе.
Хранить timestamp, а при выводе и вводе информации - учитывать заданный пояс.

Код: java
1.
2.
3.
Timestamp date = rs.getTimestamp(...);
LocalDateTime ldt = date.toLocalDateTime();
ZonedDateTime zdt = ldt.atZone(user.getZoneId());
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39116980
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
По идее, совместное хранение в одном поле времени и таймзоны противоречит требованиям 1-й нормальной формы. Так что в стандарте sql, а значит и в jdbc api такого не будет.
Хотя, не исключено, что какие-то сервера поддерживают такую экзотику
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39117018
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanraПо идее, совместное хранение в одном поле времени и таймзоны противоречит требованиям 1-й нормальной формы.
нет. Нормальные формы для выделения сущностей при проектировании.
Тут простой тип поля напр. в оракле
Код: java
1.
2.
3.
4.
5.
6.
  CREATE TABLE TTT  
  (ID NUMBER NOT NULL,  
  ....  
   DATE_REC TIMESTAMP(6) WITH LOCAL TIME ZONE DEFAULT (SYSTIMESTAMP) NOT NULL,  
   DATE_REC1 DATE  
  );
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39117064
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Petro123,
тогда уж правильнее TIMESTAMP WITH TIME ZONE , с LOCAL время просто нормализуется, и таймзона тоже не сохраняется.
Но в принципе, странный тип данных, поскольку в нем хранятся 2 значения (измерения). Вот как их сравнивать? В ORACLE сделали так:
Two TIMESTAMP WITH TIME ZONE values are considered identical if they represent the same instant in UTC, regardless of the TIME ZONE offsets stored in the data.
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39117074
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevBlazkowiczResultSet.getDate() не работает разве?
Там есть TimeZone ?
Гоню. Он ведь просто трансформируется в текущую, а это не совсем то что надо. Тогда, возможно, действительно проще хранить строкой. Зависит от отго как оно вообще используется.
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39117087
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanra,
ты прав наерно, я не вникал. У меня работодатель тоже фиксированно просит (по московскому времени смотрят).
Хотя ослик присылает в заголовках смещение.
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39117093
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevВ БД есть тип "timestamp with timezone"
Вроде, пишут, что этот тип не хранит часового пояса. Просто приводит к UTC, в то время как обычный - оставляет тот timestamp что ты прислал. То есть пояс вообще нигде не хранится. Тип влияет только на то есть ли смещения при записи и чтении.
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39117103
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanra,

Никакой идеи первой нормальной формы тут не нарушается, ибо требование атомарности, в нее не входит. Иначе хранить надо только биты - остальное не атомарно.

Требование 1 нормальной формы нарушалось бы, если б он в одном поле хранил две разные даты.

По сути вопроса, если СУБД не позволяет хранить дату с зоной в одном поле, храните все в UTC и рядом в поле TZ в которой был сделан ввод, если это так важно.
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39117105
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,
ну, называется же "дата с таймзоной".
Вообще в оракле там дофига чего. Есть таймзона ораклаБД, есть свойство коннекта, есть тип поля....
аффтару!
http://stswoon.blogspot.ru/2014/02/time-zones.html
http://rsdn.ru/forum/db/6069403.hot
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39117341
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем спасибо.

Особого прояснения не наступило ))), но на досуге почитаю для общего развития.

BlazkowiczLeonid Kudryavtsevпропущено...

Там есть TimeZone ?
Гоню. Он ведь просто трансформируется в текущую, а это не совсем то что надо. Тогда, возможно, действительно проще хранить строкой. Зависит от отго как оно вообще используется.

Мне надо просто сохранить и извлечь. Текст подходит на 100%, но как человеку ранее работавшему с БД, подход "все в текст" не очень нравится.

Ну и с бизнес задачей, когда значим timezone сталкиваюсь в первый раз.

Сергей Арсеньев...По сути вопроса, если СУБД не позволяет хранить дату с зоной в одном поле, храните все в UTC и рядом в поле TZ в которой был сделан ввод, если это так важно.

Для меня это криво. Т.к. для отладки/анализа тоже надо видеть "правильную дату" (с исходной таймзоной). UTC дата вообще даром не нужна, только для возможности корректного сравнения/сортировок.

Т.ч. "пока решил хранить все данные в виде даты + текст в ISO формате. При записи в БД пишу в два поля, при чтении из БД использую поле текст в ISO формате"
...
Рейтинг: 0 / 0
JDBC (Postgres) & java.time.ZonedDateTime
    #39118079
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevНу и с бизнес задачей, когда значим timezone сталкиваюсь в первый раз.

Сергей Арсеньев...По сути вопроса, если СУБД не позволяет хранить дату с зоной в одном поле, храните все в UTC и рядом в поле TZ в которой был сделан ввод, если это так важно.

Для меня это криво.
Криво наоборот. Если тебе нужна зона то и храни ее отдельно.
Таким образом тебе проще будет с ней оперировать и когда надо отображать время в единой шкале, а когда не надо в оригинальной. Да и сгруппировать пользователей по зонам будет проще. Но все зависит от задачи. Если же нужно только показывать оригинальное время - то строка.
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / JDBC (Postgres) & java.time.ZonedDateTime
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]