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

我有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 – 有什么办法吗?

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

虽然不是很漂亮。

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

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


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


那么,可以尝试什么:

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

 public static T ConvertOracleValue(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(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(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(ret); } string temp = value.ToString(); return ConvertHelper.ConvertValue(temp); } } else { return default(T); } return ConvertHelper.ConvertValue(value); } 

其中ConvertHelper.ConvertValue是另一个扩展:

 public static class ConvertHelper { public static T ConvertValue(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); } } 

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