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

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

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

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

ResultSet.getDate() не работает разве?
...
Рейтинг: 0 / 0
30.11.2015, 14:51
    #39116363
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JDBC (Postgres) & java.time.ZonedDateTime
...
Рейтинг: 0 / 0
30.11.2015, 16:49
    #39116543
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JDBC (Postgres) & java.time.ZonedDateTime
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
30.11.2015, 16:59
    #39116555
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JDBC (Postgres) & java.time.ZonedDateTime
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
30.11.2015, 17:15
    #39116573
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JDBC (Postgres) & java.time.ZonedDateTime
ivanrapostgre sql не хранит сведения о таймзоне, тип timestamp with timezone влияет только на работу с литералами.

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


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


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

Пока, наверное, придется хранить в тексте. Т.к. работа с новым (с 1.8) типом java.time.ZonedDateTime в java.sql похоже пока не поддерживает (((. Чуть меньше, чем полностью ((( Что лично меня расстроило (((
...
Рейтинг: 0 / 0
30.11.2015, 18:01
    #39116631
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JDBC (Postgres) & java.time.ZonedDateTime
Leonid Kudryavtsev,
там ссылка была.
Тайм зона зависит от сессии. И работают совместно не только при записи, но и при чтении
alter session set time_zone
...
Рейтинг: 0 / 0
30.11.2015, 18:06
    #39116642
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JDBC (Postgres) & java.time.ZonedDateTime
Postgre SQL не хранит и не умеет извлекать исходную таймзону из timestamp поля. Всё зависит от настроек сервера/сессии. Так что в любом случае, надо либо сохранять локальное время, либо таймзону в виде строки, в отдельное поле
...
Рейтинг: 0 / 0
30.11.2015, 18:24
    #39116661
Alexander A. Sak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JDBC (Postgres) & java.time.ZonedDateTime
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
30.11.2015, 19:29
    #39116745
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JDBC (Postgres) & java.time.ZonedDateTime
Alexander A. SakЧто-то не замечаю, что "замечательно сохраняется".
Да, не прав ((( не туда посмотрел. Извиняюсь.

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

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

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

Код: java
1.
2.
3.
Timestamp date = rs.getTimestamp(...);
LocalDateTime ldt = date.toLocalDateTime();
ZonedDateTime zdt = ldt.atZone(user.getZoneId());
...
Рейтинг: 0 / 0
01.12.2015, 09:27
    #39116980
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JDBC (Postgres) & java.time.ZonedDateTime
По идее, совместное хранение в одном поле времени и таймзоны противоречит требованиям 1-й нормальной формы. Так что в стандарте sql, а значит и в jdbc api такого не будет.
Хотя, не исключено, что какие-то сервера поддерживают такую экзотику
...
Рейтинг: 0 / 0
01.12.2015, 10:10
    #39117018
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JDBC (Postgres) & java.time.ZonedDateTime
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
01.12.2015, 10:49
    #39117064
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JDBC (Postgres) & java.time.ZonedDateTime
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
01.12.2015, 10:56
    #39117074
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JDBC (Postgres) & java.time.ZonedDateTime
Leonid KudryavtsevBlazkowiczResultSet.getDate() не работает разве?
Там есть TimeZone ?
Гоню. Он ведь просто трансформируется в текущую, а это не совсем то что надо. Тогда, возможно, действительно проще хранить строкой. Зависит от отго как оно вообще используется.
...
Рейтинг: 0 / 0
01.12.2015, 11:04
    #39117087
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JDBC (Postgres) & java.time.ZonedDateTime
ivanra,
ты прав наерно, я не вникал. У меня работодатель тоже фиксированно просит (по московскому времени смотрят).
Хотя ослик присылает в заголовках смещение.
...
Рейтинг: 0 / 0
01.12.2015, 11:10
    #39117093
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JDBC (Postgres) & java.time.ZonedDateTime
Leonid KudryavtsevВ БД есть тип "timestamp with timezone"
Вроде, пишут, что этот тип не хранит часового пояса. Просто приводит к UTC, в то время как обычный - оставляет тот timestamp что ты прислал. То есть пояс вообще нигде не хранится. Тип влияет только на то есть ли смещения при записи и чтении.
...
Рейтинг: 0 / 0
01.12.2015, 11:22
    #39117103
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JDBC (Postgres) & java.time.ZonedDateTime
ivanra,

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

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

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

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

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

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

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

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

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

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

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

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

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


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