检索存储在数据库中的日期的时区
Retrieving time zone of date stored in database
我的 J2EE 应用程序部署在集群中,服务器可以位于多个时区。例如,一台服务器在 EST 中,另一台服务器在 CST 中。
考虑一个场景,其中请求以美国东部标准时间发送到服务器并将日期和时间存储在数据库中(不带时区)。还有另一个检索相同日期的请求。但该请求可能会转到 CST 中的另一台服务器。
有什么方法可以确定数据库中存储的是哪个时区日期?
PS:我正在使用 Oracle/Java/Hibernate。
没有。如果不带时区存储DATE
,则无法查询时区。
作为开发者,您需要决定如何处理时区。请记住,您有 3 个时区:
- 数据库服务器时区。
- Web 应用程序服务器时区。
- 客户端浏览器时区。
如果洛杉矶的用户输入时间,巴黎的用户应该看到什么?
如果悉尼的用户执行操作,多伦多的用户应该看到什么操作时间戳?
在您可以回答这些问题之前,即定义您的要求,solution/implementation 不可能 code/verify。
如评论中所述,基本上有两种处理时区的方法:
- 将所有日期存储在固定时区中,例如UTC,并在需要的地方进行转换,这几乎无处不在。
- 使用时区存储日期,并根据需要转换或显示时区。用户可能更喜欢转换,但这是您做出的设计决定。
当您使用数据类型 DATE
或 TIMESTAMP
时,您没有任何关于时区的信息 - 除非您的应用程序确保在数据传输时始终使用特定时区(例如 UTC)插入或更新。
Andreas 的说法不完全正确,在 Oracle 数据库中你有三个时区:
数据库时区
你可以用DBTIMEZONE
查询它。它仅与 TIMESTAMP WITH LOCAL TIME ZONE
数据类型列相关并定义存储格式。因此,如果数据库包含 table 和 TIMESTAMP WITH LOCAL TIME ZONE
列并且该列包含数据,则您无法更改数据库上的 DBTIMEZONE
。请注意,这是 不是 SYSDATE
和 SYSTIMESTAMP
的时区
数据库服务器操作系统的时区
此时区与 SYSDATE
和 SYSTIMESTAMP
的结果相关。
您会话的时区
你可以用SESSIONTIMEZONE
查询它。它可能由您的 Web 应用程序服务器或您的客户端浏览器时区决定。 (我不是网络技术专家)如果是胖客户端,可以在您的注册表或环境变量 ORA_SDTZ
中进行设置。我不知道哪个具有优先权,也不知道当它们中的任何一个未定义时您会获得哪个值,它也可能因您的数据库提供程序和驱动程序而异。用户可以随时使用 ALTER SESSION SET TIME_ZONE=...
更改 SESSIONTIMEZONE
日期类型TIMESTAMP WITH TIME ZONE
存储带有时区信息的时间。您可以根据您的要求将它们转换为客户端本地时区或填充为插入或其他任何内容。您可以使用 EXTRACT 函数或在转换为字符串时获取时区值,例如TO_CHAR(TS_VALUE, TZH:TZM)
或 TO_CHAR(TS_VALUE, TZR)
.
日期类型TIMESTAMP WITH LOCAL TIME ZONE
还存储带有时区信息的时间。但是,它始终显示客户端当前会话时区的时间,您不能将其转换为任何其他时区(除非事先进行 CAST)。因此,当您尝试使用 TIMESTAMP WITH LOCAL TIME ZONE
值执行 TO_CHAR(TS_VALUE, 'hh24:mi:ss TZH:TZM')
时,您会收到错误消息!
我的 J2EE 应用程序部署在集群中,服务器可以位于多个时区。例如,一台服务器在 EST 中,另一台服务器在 CST 中。
考虑一个场景,其中请求以美国东部标准时间发送到服务器并将日期和时间存储在数据库中(不带时区)。还有另一个检索相同日期的请求。但该请求可能会转到 CST 中的另一台服务器。
有什么方法可以确定数据库中存储的是哪个时区日期?
PS:我正在使用 Oracle/Java/Hibernate。
没有。如果不带时区存储DATE
,则无法查询时区。
作为开发者,您需要决定如何处理时区。请记住,您有 3 个时区:
- 数据库服务器时区。
- Web 应用程序服务器时区。
- 客户端浏览器时区。
如果洛杉矶的用户输入时间,巴黎的用户应该看到什么?
如果悉尼的用户执行操作,多伦多的用户应该看到什么操作时间戳?
在您可以回答这些问题之前,即定义您的要求,solution/implementation 不可能 code/verify。
如评论中所述,基本上有两种处理时区的方法:
- 将所有日期存储在固定时区中,例如UTC,并在需要的地方进行转换,这几乎无处不在。
- 使用时区存储日期,并根据需要转换或显示时区。用户可能更喜欢转换,但这是您做出的设计决定。
当您使用数据类型 DATE
或 TIMESTAMP
时,您没有任何关于时区的信息 - 除非您的应用程序确保在数据传输时始终使用特定时区(例如 UTC)插入或更新。
Andreas 的说法不完全正确,在 Oracle 数据库中你有三个时区:
数据库时区
你可以用
DBTIMEZONE
查询它。它仅与TIMESTAMP WITH LOCAL TIME ZONE
数据类型列相关并定义存储格式。因此,如果数据库包含 table 和TIMESTAMP WITH LOCAL TIME ZONE
列并且该列包含数据,则您无法更改数据库上的DBTIMEZONE
。请注意,这是 不是SYSDATE
和SYSTIMESTAMP
的时区
数据库服务器操作系统的时区
此时区与
SYSDATE
和SYSTIMESTAMP
的结果相关。您会话的时区
你可以用
SESSIONTIMEZONE
查询它。它可能由您的 Web 应用程序服务器或您的客户端浏览器时区决定。 (我不是网络技术专家)如果是胖客户端,可以在您的注册表或环境变量ORA_SDTZ
中进行设置。我不知道哪个具有优先权,也不知道当它们中的任何一个未定义时您会获得哪个值,它也可能因您的数据库提供程序和驱动程序而异。用户可以随时使用ALTER SESSION SET TIME_ZONE=...
更改 SESSIONTIMEZONE
日期类型TIMESTAMP WITH TIME ZONE
存储带有时区信息的时间。您可以根据您的要求将它们转换为客户端本地时区或填充为插入或其他任何内容。您可以使用 EXTRACT 函数或在转换为字符串时获取时区值,例如TO_CHAR(TS_VALUE, TZH:TZM)
或 TO_CHAR(TS_VALUE, TZR)
.
日期类型TIMESTAMP WITH LOCAL TIME ZONE
还存储带有时区信息的时间。但是,它始终显示客户端当前会话时区的时间,您不能将其转换为任何其他时区(除非事先进行 CAST)。因此,当您尝试使用 TIMESTAMP WITH LOCAL TIME ZONE
值执行 TO_CHAR(TS_VALUE, 'hh24:mi:ss TZH:TZM')
时,您会收到错误消息!