Oracle.ManagedDataAccess неправильно читает даты летнего времени

Я пишу.Net приложение, которое выполняется поверх базы данных Oracle 11.2.0.2.0, в которой даты хранятся в столбцах типа "TIMESTAMP(6) WITH LOCAL TIME ZONE". Если в столбце хранится дата и она попадает в летнее время, она неправильно читается при использовании библиотеки Oracle.ManagedDataAccess. Похоже, всегда правильно писать / обновлять даты. Кроме того, при использовании библиотеки Oracle.DataAccess она всегда правильно обрабатывает даты.

В моем примере я использую часовой пояс "America/New_York" и дату / время от 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, он читается как 01.08.2014 11:00:00. Если я использую дату, которая не попадает в летнее время (например, 12.01.2014, 12:00:00), она правильно считывает дату. Есть идеи по этому поводу? Я искал по всему, но не нашел никакой документации по этому вопросу. Возможно, мне придется вернуться к Oracle.DataAccess, но надеялся избежать этого. Заранее спасибо!

1 ответ

Решение

Oracle.ManagedDataAccess все еще довольно новый, поэтому вы также всегда получаете "самые новые" ошибки.

Существуют и другие способы определения текущего часового пояса сеанса, возможно, одна из следующих работ.

  • Использование класса OracleGlobalization:

    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"
    

    Для 32-разрядного приложения x86

    Windows Registry Editor Version 5.00
    
    [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ORACLE\KEY_OraClient11g_home1]
    "ORA_SDTZ"="America/New_York"
    

    Обратите внимание, что управляемый драйвер ODP.NET не считывает значения реестра, так что это больше информация для других драйверов!

Другие вопросы по тегам