无法在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
,有办法吗?
根据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结构并手动解析