【问题标题】:Date saving in oracle not working for ISO 8601 standardoracle 中的日期保存不适用于 ISO 8601 标准
【发布时间】:2019-08-11 14:48:36
【问题描述】:

我一直在尝试在 oracle DB 中保存带有偏移量的日期,但我设法找到了带有时区偏移量的时间戳的等效数据类型。

我正在尝试将此保存到数据库。我从 UI 收到这些日期(预期格式符合 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-JUL-11 03.49.56.235000000 PM 亚洲/加尔各答 2011 年 7 月 4 日 03.49.56.235000000 PM 亚洲/加尔各答

我想将上面传递的 JSON 日期以相同的格式保存在数据库中,即以这种方式 '2011-07-04T17:19:56.235+07:00' 并希望以相同的时区格式检索它。

有人可以帮忙吗?

P.S 我使用的是 oracle 12 DB。如何使用 Java 实现这一点?

感谢阅读。

【问题讨论】:

  • 但时间戳没有以格式保存;它只是使用格式显示。如果您需要保存格式,则必须将其保存为文本。用于显示的格式在用于显示的会话或工具中设置
  • 好的,但是在那种情况下我也会丢失时区值,那么我该如何存储偏移量呢?要么将其存储为字符串,要么单独存储偏移量并进行转换?

标签: java java-time


【解决方案1】:

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      

...虽然您可能希望使用时区区域名称而不是固定偏移量。

如果您将数据拉回到填充它的任何应用程序中,您可能还需要考虑将其作为原始数据类型而不是字符串进行查询,然后将其格式化为显示/输出/onward-JSON-journey来自应用层。

【讨论】:

    【解决方案2】:

    正如上面其他人提到的,日期被正确存储(以具有 UDT 时间戳加时区的内部格式),但您的客户端以默认格式显示此日期。

    如果您需要以您选择的格式检索值,无论客户端如何,您都需要使用 TO_CHAR 函数以适当的日期格式编写您的 SELECT 语句。

    在此处查看 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-15
      • 2013-08-27
      • 1970-01-01
      • 1970-01-01
      • 2013-05-14
      • 2013-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多