Ben*_*ehn 6 c# oracle timezone datetime odp.net
从c#开始,使用odp.net,我调用一个返回游标的oracle函数.某些列的类型为"带时区的时间戳"(TSTZ).如果我直接使用OracleDataAdapter,那些列将转换为System.DateTime,并且时区信息将丢失.这是预期的行为,建议似乎是使用SafeMapping强制转换为字符串,如:
dataAdapter.SafeMapping.Add("column_name", typeof(string));
Run Code Online (Sandbox Code Playgroud)
然后我确实将TSTZ作为字符串,但它使用的格式DD-MON-YYYY HH:MI:SS.FF AM TZR如下:
23-NOV-12 08.10.12.057868000 PM ASIA/CALCUTTA
Run Code Online (Sandbox Code Playgroud)
我想要它而不是偏移(例如格式DD-MON-YYYY HH:MI:SS.FF AM TZH:TZD如:
23-NOV-12 08.10.12.057868000 PM +04:30
Run Code Online (Sandbox Code Playgroud)
当我直接查询oracle(比如在Sql Developer中)时,我可以使用
Alter Session Set Nls_Timestamp_Tz_Format='DD-MON-YYYY HH:MI:SS.FF AM TZH:TZM'
Run Code Online (Sandbox Code Playgroud)
获得我想要的格式.使用odp.net我尝试在SetSessionInfo中设置格式:
connection.Open();
OracleGlobalization glob = connection.GetSessionInfo();
glob.TimeStampTZFormat = "DD-MON-YYYY HH:MI:SS.FF AM TZH:TZM";
connection.SetSessionInfo(glob);
Run Code Online (Sandbox Code Playgroud)
以及alter session使用相同的连接执行命令,但都没有任何影响.我认为这是因为转换为字符串发生在稍后阶段,连接设置无效.
有没有其他方法让odp.net直接为我提供偏移量?我无法更改oracle db函数,因此在方法中使用例如tz_offset不是一个选项.
如果这不可能,那么将时区字符串转换为偏移量的最佳方法是什么?我正在考虑执行一个
select TZNAME, TZABBREV, tz_offset(TZNAME) as TZOFFSET
from V$TIMEZONE_NAMES
Run Code Online (Sandbox Code Playgroud)
曾经建立一个查阅表,但如果有更好的选择,会很高兴.
我的数据检索代码,包括我尝试的内容:
using (var connection = new OracleConnection(this.connectionString))
{
connection.Open();
OracleGlobalization glob = connection.GetSessionInfo();
glob.TimeStampTZFormat = "DD-MON-YYYY HH:MI:SS.FF AM TZH:TZM";
connection.SetSessionInfo(glob);
string sql = "ALTER SESSION " +
"SET NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"'";
using (var cmd = connection.CreateCommand())
{
cmd.CommandText = sql;
cmd.ExecuteNonQuery();
}
using (var cmd = connection.CreateCommand())
{
cmd.CommandText = "fn_name";
cmd.CommandType = CommandType.StoredProcedure;
cmd.BindByName = false;
var output = cmd.Parameters.Add("return_value", OracleDbType.RefCursor);
output.Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add("id", id).Direction = ParameterDirection.Input;
using (var dataAdapter = new OracleDataAdapter(cmd))
{
dataAdapter.SafeMapping.Add("TZ_COLUMN", typeof(string));
dataAdapter.TableMappings.Add("Table", "Table");
OracleGlobalization glob2 = connection.GetSessionInfo();
glob2.TimeStampTZFormat = "DD-MON-YYYY HH:MI:SS.FF AM TZH:TZM";
connection.SetSessionInfo(glob2);
dataAdapter.Fill(dataSet);
}
foreach (DataRow row in dataSet.Tables[0].Rows)
{
// column is string with timezone name, I want offset
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢
看起来一个非常简单的解决方案就是设置
dataAdapter.ReturnProviderSpecificTypes = true;
Run Code Online (Sandbox Code Playgroud)
这似乎使 ODP.net 不会执行到 .net System.DateTime 的有损转换,而是使用它自己的日期类型。
| 归档时间: |
|
| 查看次数: |
3008 次 |
| 最近记录: |