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

时间:2014-07-28 07:13:54

标签: c# asp.net regex oracle odp.net

我有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);
}

仍然传递错误。它在m后工作7 f但不超过。我用过Parse,试试ParseExact - 有什么办法吗?

3 个答案:

答案 0 :(得分:2)

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

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


这就是标准DateTime无法存储所有可能的oracle TimeStamps的原因。并且它的解析函数在TimeStamp的更精确的字符串表示中失败。


那么,可以尝试的是什么:

答案 1 :(得分:2)

根据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);

虽然不是很漂亮。

答案 2 :(得分:2)

一旦我们开始使用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);
        }
}

这在我们的测试,集成和生产环境中起到了很大的作用。