java - Oracle 存储日期的 TIMESTAMP 数据类型是否根据本地时区进行调整?
问题描述
我有一个使用 Spring JDBC 将数据存储到 Oracle 的 java 应用程序。数据包括我们将来用来查询某些数据的时间戳/日期。
日期字段在 DDL SQL 文件中的定义如下:
JobExecution {
START_TIME TIMESTAMP DEFAULT NULL ,
END_TIME TIMESTAMP DEFAULT NULL
...
}
更新这些字段的 Java 代码如下所示:
lastJobExecution.setEndTime(new Date(System.currentTimeMillis()));
new Date(System.currentTimeMillis())
根据以下文档以 UTC 格式存储当前时间。的文档System.currentTimeMillis()
说它返回以下内容:
当前时间与 UTC 1970 年 1 月 1 日午夜之间的差异,以毫秒为单位。
的文档Date
说以下内容:
分配一个 Date 对象并将其初始化以表示自称为“纪元”的标准基准时间(即 1970 年 1 月 1 日 00:00:00 GMT)以来的指定毫秒数。
参数: date - 自 1970 年 1 月 1 日 00:00:00 GMT 以来的毫秒数。另请参阅: System.currentTimeMillis()
但是,当我使用 SQL 开发人员连接到 oracle 数据库时,日期似乎是按照本地时间而不是 UTC 存储的。
问题 :
- Oracle 会
TIMESTAMP
根据当地时间调整日期吗?我在 Oracle 文档的任何地方都找不到明确写的。 - 如果是的话,处理这个问题的最佳方法是什么。一种方法是每次我从该表中读取数据时将其转换为 UTC。另一种方法可能是将其存储为 UTC 格式本身。
解决方案
不,TIMESTAMP
数据类型不存储任何时区信息。
请参阅日期时间数据类型文档。
Oracle 提供了两种支持时区的时间戳数据类型:
TIMESTAMP WITH TIME ZONE
顾名思义,它存储带有时区信息的时间戳。时区可以作为区域名称(例如Europe/Zurich
)或 UTC 偏移量给出。请注意,您不能直接在此类列上创建索引。相反,Oracle 创建一个虚拟列,SYS_EXTRACT_UTC(<your column>)
并在此虚拟列上创建索引。您可能需要相应地调整您的查询。
通常,当您使用时区时,一种常见的方法是将所有时间存储为 UTC 时间,然后客户端将其转换为本地时间。这完全由第二种数据类型提供:
TIMESTAMP WITH LOCAL TIME ZONE
在 a中,TIMESTAMP WITH LOCAL TIME ZONE
所有值都存储在DBTIMEZONE
(默认为 UTC),但值始终显示在当前用户会话时区中。
另请注意,所有值的比较(例如<, >, =, >=, <=
)TIMESTAMP WITH [LOCAL] TIME ZONE
都是根据 UTC 值执行的。
推荐阅读
- spring-integration - 使用 Spring Integration 读取文件并希望使用过滤器进行排序和文件提取
- mysql - MySQL在选择时只得到一行重复的结果
- python - 创建空间相关噪声的更快方法?
- android - 如何在 Flutter 应用中正确设置 redirect_uri?
- ios - 如果 Chromecast 是内置电视,则无法检测到它
- python - django - 休息框架响应内容协商没有发生
- dataframe - 在R中,当x和y重复时,我想提取z的最小值
- google-apps-script - 进程运行时在 Google 表格桌面和移动应用中添加警告或信息消息的问题
- android - 键盘出现时如何阻止EditText向上移动
- python - 没有 if 但有 else 的列表理解