无法在c#中解析Oracle时间戳

本文关键字:Oracle 时间戳 | 更新日期: 2023-09-27 18:15:05

我有Oracle时间戳:

string timestamp = "23-JUN-14 09.39.04.000000000 AM";

我无法将其解析为系统日期时间对象。我使用:

CultureInfo provider = CultureInfo.InvariantCulture;
                String format = "yy-MMM-dd hh:mm:ss:fffffff";
                string timestamp = "10-DEC-07 10.32.47.797201123 AM";
                {
                    var date = DateTime.ParseExact(timestamp, format, provider);
                    DateTime dateTime = DateTime.ParseExact(timestamp.ToString(), "dd-MMM-y HH:mm:ss", CultureInfo.InvariantCulture);
}

仍在传递错误。它在晚上7点工作,但不会超过7点。我用了试Parse,试ParseExact,有办法吗?

无法在c#中解析Oracle时间戳

根据https://stackoverflow.com/a/23198962/328864,没有办法跳过一个确切模式的部分,所以我猜你可以这样做:

CultureInfo provider = CultureInfo.InvariantCulture;
string timestamp = "10-DEC-07 10.32.47.797201123 AM";
String format = String.Format("yy-MMM-dd hh.mm.ss.fffffff{0} tt", timestamp.Substring(26,2));
DateTime date = DateTime.ParseExact(timestamp, format, provider);
Console.WriteLine(date);

一旦我们开始使用ODP。. NET,我们必须实现如下扩展:

public static T ConvertOracleValue<T>(this object value)
{
     if (value != null)
     {
          Type typeOfValue = value.GetType();
          if (typeOfValue.Namespace.Contains("Oracle.DataAccess"))
          {
              if (typeOfValue.Name.Equals("OracleTimeStamp"))
              {
                   int tempInt = 0;
                   Oracle.DataAccess.Types.OracleTimeStamp ots = (Oracle.DataAccess.Types.OracleTimeStamp)value;
                   tempInt = Int32.TryParse(ots.Millisecond.ToString("000").Substring(0, 3), out tempInt) ? tempInt : 0;
                   DateTime ret = new DateTime(ots.Year, ots.Month, ots.Day, ots.Hour, ots.Minute, ots.Second, tempInt);
                    return ConvertHelper.ConvertValue<T>(ret);
              }
              if (typeOfValue.Name.Equals("OracleTimeStampLTZ"))
              {
                    int tempInt = 0;
                    Oracle.DataAccess.Types.OracleTimeStampLTZ ots = (Oracle.DataAccess.Types.OracleTimeStampLTZ)value;
                    tempInt = Int32.TryParse(ots.Millisecond.ToString("000").Substring(0, 3), out tempInt) ? tempInt : 0;
                    DateTime ret = new DateTime(ots.Year, ots.Month, ots.Day, ots.Hour, ots.Minute, ots.Second, tempInt);
                    return ConvertHelper.ConvertValue<T>(ret);
              }
              if (typeOfValue.Name.Equals("OracleTimeStampTZ"))
              {
                    int tempInt = 0;
                    Oracle.DataAccess.Types.OracleTimeStampTZ ots = (Oracle.DataAccess.Types.OracleTimeStampTZ)value;
                    tempInt = Int32.TryParse(ots.Millisecond.ToString("000").Substring(0, 3), out tempInt) ? tempInt : 0;
                    DateTime ret = new DateTime(ots.Year, ots.Month, ots.Day, ots.Hour, ots.Minute, ots.Second, tempInt);
                    return ConvertHelper.ConvertValue<T>(ret);
              }
              string temp = value.ToString();
              return ConvertHelper.ConvertValue<T>(temp);
          }
      }
      else
      {
           return default(T);
      }
      return ConvertHelper.ConvertValue<T>(value);
}

ConvertHelper的地方。ConvertValue是另一个扩展:

public static class ConvertHelper
    {
        public static T ConvertValue<T>(object value)
        {
            Type typeOfT = typeof(T);
            if (typeOfT.BaseType != null && typeOfT.BaseType.ToString() == "System.Enum")
            {
                return (T)Enum.Parse(typeOfT, Convert.ToString(value));
            }
            if ((value == null || value == Convert.DBNull) && (typeOfT.IsValueType))
            {
                return default(T);
            }
            if (value is IConvertible)
            {
                return (T)Convert.ChangeType(value, typeOfT, new CultureInfo("en-GB"));
            }
            return (T)Convert.ChangeType(value, typeOfT);
        }
}

这在我们的测试、集成和生产环境中都非常有效。

。. NET DateTime结构的精度为tick - 100纳秒- 0.0000001秒-点后7位小数。

Oracle TimeStamp的精度可达纳秒- 0.000000001 -点后9位小数。


这就是为什么标准DateTime不能存储所有可能的oracle时间戳。它的解析函数在更精确的TimeStamp字符串表示上失败。


那么,可以尝试什么:

  • 将查询中的时间戳格式化为可由DataTime解析的格式(必要时丢失精度)- http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm
  • 或者创建自己的更精确的CustomTimeStamp .Net结构并手动解析