Сохранение даты в Oracle не работает для стандарта ISO 8601 - PullRequest
0 голосов
/ 20 марта 2019

Я пытался сохранить дату со смещением в oracle DB, мне удалось найти эквивалентный тип данных для метки времени со смещением часового пояса.

Я пытаюсь сохранить это в БД. Я получаю эти даты из пользовательского интерфейса (ожидаемый формат - ISO-8601). У меня есть следующий код. POJO Содержит два поля.

@Column(columnDefinition = "TIMESTAMP WITH TIME ZONE")
private ZonedDateTime zonedDateTime;

@Column(columnDefinition = "TIMESTAMP WITH TIME ZONE")
private OffsetDateTime offSetDateTime;

DTO имеет те же поля с тем же типом данных, но с аннотацией @JsonFormat, как показано ниже:

@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZ")
private ZonedDateTime zonedDateTime;

@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZ")
private OffsetDateTime offSetDateTime;

Дата, которую я передаю от Почтальона, выглядит следующим образом:

{
   "zonedDateTime"  : "2011-07-04T17:19:56.235+07:00",
   "offSetDateTime" : "2011-07-04T17:19:56.235+07:00"
}

Что сохраняется в БД следующим образом:

04-ИЮЛ-11 03.49.56.235000000 PM АЗИЯ / КАЛЬКУТТА 04-ИЮЛ-11 03.49.56.235000000 PM АЗИЯ / КАЛЬКУТА

Я хочу сохранить вышеприведенную дату JSON в том же формате в базе данных, т.е. «2011-07-04T17: 19: 56.235 + 07: 00», и хочу получить ее в том же формате часового пояса.

Может кто-нибудь помочь, пожалуйста?

P.S. Я использую Oracle 12 DB. Как я могу добиться этого с помощью Java?

Спасибо за чтение.

Ответы [ 2 ]

1 голос
/ 20 марта 2019

Oracle хранит даты и метки времени в своих собственных внутренних форматах. Вы просто видите, как ваш клиент выбирает их отображение (возможно, с использованием настроек сеанса NLS). Если вы хотите увидеть значение в определенном формате, вам нужно преобразовать его в строку; с CTE для вашего значения образца:

with your_table (zonedDateTime) as (
  select to_timestamp_tz('04-JUL-11 03.49.56.235000000 PM ASIA/CALCUTTA', 'DD-MON-RR HH:MI:SS.FF9 AM TZR')
  from dual
)
select zonedDateTime as session_format,
  to_char(zonedDateTime, 'YYYY-MM-DD"T"HH24:MI:SS.FF3TZH:TZM') as iso_format
from your_table;

SESSION_FORMAT                                ISO_FORMAT                         
--------------------------------------------- -----------------------------------
04-JUL-11 03:49:56.235000000 PM ASIA/CALCUTTA 2011-07-04T15:49:56.235+05:30      

Похоже, что часовой пояс конвертируется как часть вашего процесса сохранения, возможно, неявно из-за разницы между часовым поясом клиента и сервера при выполнении вставки; но это тот же момент времени.

Вы можете преобразовать обратно в определенное смещение часового пояса как часть этого запроса:

select zonedDateTime as session_format,
  to_char(zonedDateTime at time zone '+07:00', 'YYYY-MM-DD"T"HH24:MI:SS.FF3TZH:TZM') as iso_format
from your_table;

SESSION_FORMAT                                ISO_FORMAT                         
--------------------------------------------- -----------------------------------
04-JUL-11 03:49:56.235000000 PM ASIA/CALCUTTA 2011-07-04T17:19:56.235+07:00      

... хотя вы, вероятно, хотите использовать имя региона часового пояса, а не фиксированное смещение.

Если вы перетаскиваете данные обратно в любое приложение, которое их заполняет, вы можете также рассмотреть возможность запроса их как исходного типа данных, а не как строки, а затем отформатировать их для display / output / onward-JSON-trip из прикладного уровня.

0 голосов
/ 20 марта 2019

Как уже упоминалось выше, дата хранится правильно (во внутреннем формате, который имеет метку времени UDT плюс часовой пояс), но ваш клиент отображает эту дату в формате по умолчанию.

Если вам нужно получить значение в выбранном вами формате независимо от клиента, вам нужно написать оператор SELECT с помощью функции TO_CHAR с соответствующим форматом даты.

См. Использование TO_CHAR здесь: https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions180.htm

Смотрите форматы даты здесь: https://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm#i34924

...