博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Sqlite.net 读取DateTime异常的解决方案
阅读量:4962 次
发布时间:2019-06-12

本文共 4951 字,大约阅读时间需要 16 分钟。

以前在处理DateTime的时候,为了屏蔽不同数据库的差异,经常将DateTime保存成字符串,只要服务器不切换本地化表示方法,这种方案肯定是没有问题的。只是在读取和保存的时候需要各做一次转换,(实际上System.Data.Sqlite也会做类似的事情,因此性能上几乎没有差异)。

这种方法延续到Sqlite一样没有问题,最近看一个开源项目,里面直接用的DateTime,里面用了Utc格式,后来在日志中发现总是有格式异常的报警,仔细调阅了一下日志发现问题都是一样的,根源指到了System.Data.Sqlite。

 

System.FormatException: String was not recognized as a valid DateTime.

 

at System.DateTimeParse.ParseExactMultiple(String s, String[] formats, DateTimeFormatInfo dtfi, DateTimeStyles style)

at System.DateTime.ParseExact(String s, String[] formats, IFormatProvider provider, DateTimeStyles style)
at System.Data.SQLite.SQLiteConvert.ToDateTime(String dateText)
at System.Data.SQLite.SQLite3.GetDateTime(SQLiteStatement stmt, Int32 index)
at System.Data.SQLite.SQLite3.GetValue(SQLiteStatement stmt, Int32 index, SQLiteType typ)
at System.Data.SQLite.SQLiteDataReader.GetValue(Int32 i)

 

对应源代码为:

Sqlite3.cs

   

internal
 
override
 DateTime GetDateTime(SQLiteStatement stmt, 
int
 index)
    {
#if
 !SQLITE_STANDARD
      
int
 len;
      
return
 ToDateTime(UnsafeNativeMethods.sqlite3_column_text_interop(stmt._sqlite_stmt, index, 
out
 len), len);
#else
      
return
 ToDateTime(UnsafeNativeMethods.sqlite3_column_text(stmt._sqlite_stmt, index), 
-
1
);
#endif
    }

 

 

SQLiteConvert.cs

 

///
 
<summary>
    
///
 Converts a string into a DateTime, using the current DateTimeFormat specified for the connection when it was opened.
    
///
 
</summary>
    
///
 
<remarks>
    
///
 Acceptable ISO8601 DateTime formats are:
    
///
   yyyy-MM-dd HH:mm:ss
    
///
   yyyyMMddHHmmss
    
///
   yyyyMMddTHHmmssfffffff
    
///
   yyyy-MM-dd
    
///
   yy-MM-dd
    
///
   yyyyMMdd
    
///
   HH:mm:ss
    
///
   THHmmss
    
///
 
</remarks>
    
///
 
<param name="dateText">
The string containing either a Tick value, a JulianDay double, or an ISO8601-format string
</param>
    
///
 
<returns>
A DateTime value
</returns>
    
public
 DateTime ToDateTime(
string
 dateText)
    {
      
switch
 (_datetimeFormat)
      {
        
case
 SQLiteDateFormats.Ticks:
          
return
 
new
 DateTime(Convert.ToInt64(dateText, CultureInfo.InvariantCulture));
        
case
 SQLiteDateFormats.JulianDay:
          
return
 ToDateTime(Convert.ToDouble(dateText, CultureInfo.InvariantCulture));
        
default
:
          
return
 DateTime.ParseExact(dateText, _datetimeFormats, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None);
      }
    }

 

 

问题就出现在这里面,ISO8601规范,无非就有两种办法,

 

一种是在存储的时候datetime格式要遵守ISO8601格式规范,即转码.ToString("S");

 

另外一种方法就是扩展_datetimeFormats,让其支持其他格式。

原始定义为:

 

///
 
<summary>
    
///
 An array of ISO8601 datetime formats we support conversion from
    
///
 
</summary>
    
private
 
static
 
string
[] _datetimeFormats 
=
 
new
 
string
[] {
      
"
THHmmss
"
,
      
"
THHmm
"
,
      
"
HH:mm:ss
"
,
      
"
HH:mm
"
,
      
"
HH:mm:ss.FFFFFFF
"
,
      
"
yy-MM-dd
"
,
      
"
yyyy-MM-dd
"
,
      
"
yyyy-MM-dd HH:mm:ss.FFFFFFF
"
,
      
"
yyyy-MM-dd HH:mm:ss
"
,
      
"
yyyy-MM-dd HH:mm
"
,                               
      
"
yyyy-MM-ddTHH:mm:ss.FFFFFFF
"
,
      
"
yyyy-MM-ddTHH:mm
"
,
      
"
yyyy-MM-ddTHH:mm:ss
"
,
      
"
yyyyMMddHHmmss
"
,
      
"
yyyyMMddHHmm
"
,
      
"
yyyyMMddTHHmmssFFFFFFF
"
,
      
"
yyyyMMdd
"
    };

 

修改后的定义为:

 

///
 
<summary>
    
///
 An array of ISO8601 datetime formats we support conversion from
    
///
 
</summary>
    
private
 
static
 
string
[] _datetimeFormats 
=
 
new
 
string
[] {
      
"
THHmmss
"
,
      
"
THHmm
"
,
      
"
HH:mm:ss
"
,
      
"
HH:mm
"
,
      
"
HH:mm:ss.FFFFFFF
"
,
      
"
yy-M-d
"
,
      
"
yy-M-dd
"
,
      
"
yy-MM-dd
"
,
      
"
yyyy-M-d
"
,
      
"
yyyy-M-dd
"
,
      
"
yyyy-MM-dd
"
,
      
"
yyyy-M-d H:mm:ss.FFFFFFF
"
,
      
"
yyyy-M-d H:mm:ss
"
,
      
"
yyyy-M-d H:mm
"
,                         
      
"
yyyy-M-d HH:mm:ss.FFFFFFF
"
,
      
"
yyyy-M-d HH:mm:ss
"
,
      
"
yyyy-M-d HH:mm
"
,                               
      
"
yyyy-M-dTHH:mm:ss.FFFFFFF
"
,
      
"
yyyy-M-dTHH:mm
"
,
      
"
yyyy-M-dTHH:mm:ss
"
,
      
"
yyyy-M-dd H:mm:ss.FFFFFFF
"
,
      
"
yyyy-M-dd H:mm:ss
"
,
      
"
yyyy-M-dd H:mm
"
,                         
      
"
yyyy-M-dd HH:mm:ss.FFFFFFF
"
,
      
"
yyyy-M-dd HH:mm:ss
"
,
      
"
yyyy-M-dd HH:mm
"
,                               
      
"
yyyy-M-ddTHH:mm:ss.FFFFFFF
"
,
      
"
yyyy-M-ddTHH:mm
"
,
      
"
yyyy-M-ddTHH:mm:ss
"
,
      
"
yyyy-MM-dd H:mm:ss.FFFFFFF
"
,
      
"
yyyy-MM-dd H:mm:ss
"
,
      
"
yyyy-MM-dd H:mm
"
,                         
      
"
yyyy-MM-dd HH:mm:ss.FFFFFFF
"
,
      
"
yyyy-MM-dd HH:mm:ss
"
,
      
"
yyyy-MM-dd HH:mm
"
,                               
      
"
yyyy-MM-ddTHH:mm:ss.FFFFFFF
"
,
      
"
yyyy-MM-ddTHH:mm
"
,
      
"
yyyy-MM-ddTHH:mm:ss
"
,
      
"
yyyyMMddHHmmss
"
,
      
"
yyyyMMddHHmm
"
,
      
"
yyyyMMddTHHmmssFFFFFFF
"
,
      
"
yyyyMMdd
"
,
      
"
yy/M/d
"
,
      
"
yy/M/dd
"
,
      
"
yy/MM/dd
"
,
      
"
yyyy/M/d
"
,
      
"
yyyy/M/dd
"
,
      
"
yyyy/MM/dd
"
,
      
"
yyyy/M/d H:mm:ss.FFFFFFF
"
,
      
"
yyyy/M/d H:mm:ss
"
,
      
"
yyyy/M/d H:mm
"
,                         
      
"
yyyy/M/d HH:mm:ss.FFFFFFF
"
,
      
"
yyyy/M/d HH:mm:ss
"
,
      
"
yyyy/M/d HH:mm
"
,                               
      
"
yyyy/M/dTHH:mm:ss.FFFFFFF
"
,
      
"
yyyy/M/dTHH:mm
"
,
      
"
yyyy/M/dTHH:mm:ss
"
,
      
"
yyyy/M/dd H:mm:ss.FFFFFFF
"
,
      
"
yyyy/M/dd H:mm:ss
"
,
      
"
yyyy/M/dd H:mm
"
,                         
      
"
yyyy/M/dd HH:mm:ss.FFFFFFF
"
,
      
"
yyyy/M/dd HH:mm:ss
"
,
      
"
yyyy/M/dd HH:mm
"
,                               
      
"
yyyy/M/ddTHH:mm:ss.FFFFFFF
"
,
      
"
yyyy/M/ddTHH:mm
"
,
      
"
yyyy/M/ddTHH:mm:ss
"
,
      
"
yyyy/MM/dd H:mm:ss.FFFFFFF
"
,
      
"
yyyy/MM/dd H:mm:ss
"
,
      
"
yyyy/MM/dd H:mm
"
,                         
      
"
yyyy/MM/dd HH:mm:ss.FFFFFFF
"
,
      
"
yyyy/MM/dd HH:mm:ss
"
,
      
"
yyyy/MM/dd HH:mm
"
,                               
      
"
yyyy/MM/ddTHH:mm:ss.FFFFFFF
"
,
      
"
yyyy/MM/ddTHH:mm
"
,
      
"
yyyy/MM/ddTHH:mm:ss
"
    };

 

 

然后重新编译一下,就OK了,您也可以根据具体的使用情况进行扩展。

 

最后还有一种办法,就是Ticks,这种方案需要在连接字符串上设置,DateTimeFormat=Ticks(默认是ISO8601),这种方案和最开始的方案类似,第一种方案是转换为字符串,这种是转换为int64,然后由系统的转换方法实现转换。

 

修改后的Sqlite,

转载于:https://www.cnblogs.com/chinull/archive/2011/09/06/2168838.html

你可能感兴趣的文章
求一个字符串中最长回文子串的长度(承接上一个题目)
查看>>
简单权限管理系统原理浅析
查看>>
springIOC第一个课堂案例的实现
查看>>
求输入成绩的平均分
查看>>
php PDO (转载)
查看>>
wordpress自动截取文章摘要代码
查看>>
[置顶] 一名优秀的程序设计师是如何管理知识的?
查看>>
scanf和gets
查看>>
highcharts 图表实例
查看>>
ubuntu下如何查看用户登录及系统授权相关信息
查看>>
秋季学期学习总结
查看>>
SpringBoot 优化内嵌的Tomcat
查看>>
【LaTeX】E喵的LaTeX新手入门教程(1)准备篇
查看>>
highcharts曲线图
查看>>
extjs动态改变样式
查看>>
PL/SQL Developer 查询的数据有乱码或者where 字段名=字段值 查不出来数据
查看>>
宏定义
查看>>
ubuntu12.04 串口登录系统配置
查看>>
poj3061
查看>>
linux--多进程进行文件拷贝
查看>>