Oracle.ManagedDataAccess 读取夏令时日期不正确
Oracle.ManagedDataAccess reads DST dates incorrectly
我正在编写一个运行在 Oracle 11.2.0.2.0 数据库之上的 .Net 应用程序,该数据库将日期存储在 "TIMESTAMP(6) WITH LOCAL TIME ZONE" 类型的列中。当列中存储了一个日期并且它在 DST 范围内时,使用 Oracle.ManagedDataAccess 库时会错误地读取日期。它似乎总是 write/update 日期正确。此外,在使用 Oracle.DataAccess 库时,它始终可以正确处理日期。
在我的示例中,我使用的时区 'America/New_York' 和 date/time 为 08/01/2014 12:00:00。以下是错误读取日期的代码片段:
IDbConnection cxn = new Oracle.ManagedDataAccess.Client.OracleConnection(ConnStr);
// Using the following library works correctly:
// IDbConnection cxn = new Oracle.DataAccess.Client.OracleConnection(ConnStr);
cxn.Open();
var cmd = cxn.CreateCommand();
cmd.CommandText = "alter session set time_zone='America/New_York'";
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT TEST_DATE FROM TEST_TABLE WHERE ROWNUM=1";
return (DateTime)cmd.ExecuteScalar();
当列更新为值 08/01/2014 12:00:00 时,它被读取为 08/01/2014 11:00:00。如果我使用不属于夏令时的日期(例如 12/01/2014 12:00:00),它会正确读取日期。对此有什么想法吗?我一直在搜索,但没有找到关于此问题的任何文档。我可能不得不切换回 Oracle.DataAccess,但我希望避免它。提前致谢!
Oracle.ManagedDataAccess 仍然很新,因此您也总是遇到 "newest" 错误。
还有其他方法可以定义您当前的会话时区,可能是以下方法之一。
OracleGlobalization的用法class:
this.Connection = new OracleConnection();
this.Connection.ConnectionString = ...
this.Connection.Open();
OracleGlobalization info = this.Connection.GetSessionInfo();
info.TimeZone = "America/New_York";
this.Connection.SetSessionInfo(info);
仔细测试一下,我对OracleGlobalization
的体验很差。还要测试 this.Connection.OpenWithNewPassword(...);
,而不仅仅是 this.Connection.Open();
。当我使用 OpenWithNewPassword
我的应用程序崩溃时没有任何错误(即使在 Visual Studio 中调试!)
将 ORA_SDTZ
设置为系统中的环境变量。
在您的注册表中设置时区,它是 HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_{YOUR_ORACLE_HOME_NAME}\ORA_SDTZ
的字符串值,例如
对于 x64(64 位)应用程序
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OraClient11g_home1]
"ORA_SDTZ"="America/New_York"
对于 x86(32 位)应用程序
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ORACLE\KEY_OraClient11g_home1]
"ORA_SDTZ"="America/New_York"
注意,ODP.NET Managed Driver 不读取任何注册表值,所以这更多是作为其他驱动程序的信息!
我正在编写一个运行在 Oracle 11.2.0.2.0 数据库之上的 .Net 应用程序,该数据库将日期存储在 "TIMESTAMP(6) WITH LOCAL TIME ZONE" 类型的列中。当列中存储了一个日期并且它在 DST 范围内时,使用 Oracle.ManagedDataAccess 库时会错误地读取日期。它似乎总是 write/update 日期正确。此外,在使用 Oracle.DataAccess 库时,它始终可以正确处理日期。
在我的示例中,我使用的时区 'America/New_York' 和 date/time 为 08/01/2014 12:00:00。以下是错误读取日期的代码片段:
IDbConnection cxn = new Oracle.ManagedDataAccess.Client.OracleConnection(ConnStr);
// Using the following library works correctly:
// IDbConnection cxn = new Oracle.DataAccess.Client.OracleConnection(ConnStr);
cxn.Open();
var cmd = cxn.CreateCommand();
cmd.CommandText = "alter session set time_zone='America/New_York'";
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT TEST_DATE FROM TEST_TABLE WHERE ROWNUM=1";
return (DateTime)cmd.ExecuteScalar();
当列更新为值 08/01/2014 12:00:00 时,它被读取为 08/01/2014 11:00:00。如果我使用不属于夏令时的日期(例如 12/01/2014 12:00:00),它会正确读取日期。对此有什么想法吗?我一直在搜索,但没有找到关于此问题的任何文档。我可能不得不切换回 Oracle.DataAccess,但我希望避免它。提前致谢!
Oracle.ManagedDataAccess 仍然很新,因此您也总是遇到 "newest" 错误。
还有其他方法可以定义您当前的会话时区,可能是以下方法之一。
OracleGlobalization的用法class:
this.Connection = new OracleConnection(); this.Connection.ConnectionString = ... this.Connection.Open(); OracleGlobalization info = this.Connection.GetSessionInfo(); info.TimeZone = "America/New_York"; this.Connection.SetSessionInfo(info);
仔细测试一下,我对
OracleGlobalization
的体验很差。还要测试this.Connection.OpenWithNewPassword(...);
,而不仅仅是this.Connection.Open();
。当我使用OpenWithNewPassword
我的应用程序崩溃时没有任何错误(即使在 Visual Studio 中调试!)将
ORA_SDTZ
设置为系统中的环境变量。在您的注册表中设置时区,它是
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_{YOUR_ORACLE_HOME_NAME}\ORA_SDTZ
的字符串值,例如对于 x64(64 位)应用程序
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OraClient11g_home1] "ORA_SDTZ"="America/New_York"
对于 x86(32 位)应用程序
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ORACLE\KEY_OraClient11g_home1] "ORA_SDTZ"="America/New_York"
注意,ODP.NET Managed Driver 不读取任何注册表值,所以这更多是作为其他驱动程序的信息!