Java 如何以字符串格式从Oracle数据库中收集操作系统的时区?(使用tz将日期迁移/转换为ts)
我想更新一个数据库表,它使用date type来Java 如何以字符串格式从Oracle数据库中收集操作系统的时区?(使用tz将日期迁移/转换为ts),java,oracle,date,timezone,stored-functions,Java,Oracle,Date,Timezone,Stored Functions,我想更新一个数据库表,它使用date type来timestamp with timezonetype,以便旧日期获得正确的时区信息 简单的转换对我来说并不好,因为如果时区是UTC+2小时(UTC+1+1小时用于日光保存),并且我尝试将日期转换为带有时区的时间戳,则数据库表中的所有日期都与时区偏移量相同+2小时,无论是夏季还是冬季日期 我已经可以编写一个SQL查询,它可以确定日期是否在DaylightSave time中,如果我知道字符串格式的当前时区,例如“Europe/Berlin”。问题是
timestamp with timezone
type,以便旧日期获得正确的时区信息
简单的转换对我来说并不好,因为如果时区是UTC+2小时(UTC+1+1小时用于日光保存),并且我尝试将日期转换为带有时区的时间戳,则数据库表中的所有日期都与时区偏移量相同+2小时,无论是夏季还是冬季日期
我已经可以编写一个SQL查询,它可以确定日期是否在DaylightSave time中,如果我知道字符串格式的当前时区,例如“Europe/Berlin”。问题是dbtimezone和sessiontimezone也可以以其他格式存储(+02:00,CET等)。我无法以静态方式轻松设置当前sessiontimezone,因为全球多个地方的客户都有自己的数据库,但使用的是通用的更新脚本。
timestamp的Express方法也无能为力,因为它无法将偏移量映射到指定的时区
我见过一个解决方案,它使用java存储过程来获取操作系统的时区,而不是Oracles时区。不幸的是,我们使用的是Oracle12c,它包含一个较旧的JRE(我认为它是1.6版本)。因此,尽管Java1.8能够很好地处理时区和夏令时(它使用更新的tzmapping表),但它对我来说并不适用。我尝试过它,如果我从Netbeans运行测试,它会返回正确的时区ID(欧洲/柏林格式),但即使它被Oracle SQL开发人员SQLPlus(我们用于运行更新脚本)接受,它也只显示+02:00
我已经尝试使用JodaTime(为了被SQL*Plus接受,重新编译到Java 1.6中)。最新的JodaTimes在理论上使用了自己的映射表。我在StackOverflow上读到,如果它不能从user.timezone
变量中收集时区,那么它将转向java.util
,正如我所提到的,这是不好的。如果不成功,则使用UTC。但我不清楚为什么它不能从user.timezone
systemm变量中获取时区。这可能是许可问题吗?
或者我怎么可能解决这个问题?谢谢大家! 如果数据已经在Oracle SQL表中,并且必须转换为带时区的时间戳(例如,在同一表中创建的新列中),则不需要显式转到操作系统,也不需要使用Java或其他任何东西,Oracle数据库本身除外 您的问题不清楚您是否必须假定“日期”在服务器时区(您提到的“数据库”通常指服务器)或客户端时区(您提到的“会话”指客户端)。无论哪种方式:
update <your_table>
set <timestamp_with_time_zone_col> =
from_tz(cast<date_col> as timestamp, dbtimezone)
;
标题中的问题 如何以字符串格式从Oracle数据库中收集操作系统的时区 这很容易回答。运行以下语句:
SELECT TO_CHAR(SYSTIMESTAMP, 'tzr') FROM dual;
但是我假设你有一个不同的问题,但是我不完全理解
当您有一列带有时区的时间戳时,时区信息可用。像+02:00
这样的时区没有任何夏令时,无论是夏季还是冬季,它总是比UTC提前2小时。像欧洲/柏林
或CET
这样的时区适用夏令时
如果您有一个时间,例如2018-06-22 10:00:00+02:00
,那么您根本不知道这是否意味着开启夏令时的欧洲/柏林或非洲/开罗,总是比UTC提前+02:00小时-您无法检索此类信息
如果在日期
(或时间戳
)列中有数据,则您根本没有任何时区信息,因此在没有进一步信息的情况下,无法将这些值转换为带时区的时间戳
在操作系统的时区中存储时间是毫无用处的。将它们存储在UTC中,或使用数据类型时间戳和本地时区
。带有本地时区的时间戳中的数据存储在DBTIMEZONE
(建议设置为UTC,但实际上与您无关)中,并且始终且仅显示在当前用户SESSIONTIMEZONE中,我无法读取所有未格式化的文本,但如果我正确理解您的问题…-为什么不使用带有本地时区的时间戳
数据类型,并使用它呢?在任何情况下:数据库服务器的时区(在创建或上次更改数据库时设置)在DBTIMEZONE
中可用,而客户端时区在SESSIONTIMEZONE
中可用。根据您的具体需要,您可以使用一个或另一个作为_TZ()
的的第二个参数(第一个参数是您的日期,先转换为时间戳)。如果您要将问题文本格式化为更可读的格式,您将有更好的机会获得答案,并且不会因为问题不清楚而关闭问题。请参阅.Reading system propertyuser.timezone
,Java中的该属性不需要任何权限。您确定它的值正确吗?您可能需要使用System.getProperty
和System.setProperty
。后者可能只有在您在接触任何日期和时间类之前才有效。PS您可以将其作为Joda time的替代方案。它为您提供了Java 1.8Java.time
的核心功能,并在Java 1.6上运行。我认为,如果我能够以“大陆/城市”格式获得DB服务器的当前时区,我将能够为最初没有此信息的日期计算正确的tz信息。我假设所有日期都保存在DB服务器的时间(区域)中,并且这和创建
SELECT TO_CHAR(SYSTIMESTAMP, 'tzr') FROM dual;