@@ -37,6 +37,10 @@ public static class DateTimeSerializer
3737 public const string UnspecifiedOffset = "-0000" ;
3838 public const string UtcOffset = "+0000" ;
3939
40+ private const char XsdTimeSeparator = 'T' ;
41+ private static readonly int XsdTimeSeparatorIndex = XsdDateTimeFormat . IndexOf ( XsdTimeSeparator ) ;
42+ private const string XsdUtcSuffix = "Z" ;
43+
4044 /// <summary>
4145 /// If AlwaysUseUtc is set to true then convert all DateTime to UTC.
4246 /// </summary>
@@ -73,12 +77,14 @@ public static DateTime ParseShortestXsdDateTime(string dateTimeStr)
7377 return DateTime . Parse ( dateTimeStr , CultureInfo . InvariantCulture ) . Prepare ( ) ;
7478 }
7579
80+ dateTimeStr = RepairXsdTimeSeparator ( dateTimeStr ) ;
81+
7682 if ( dateTimeStr . Length == XsdDateTimeFormatSeconds . Length )
7783 return DateTime . ParseExact ( dateTimeStr , XsdDateTimeFormatSeconds , null , DateTimeStyles . AdjustToUniversal ) . Prepare ( parsedAsUtc : true ) ;
7884
7985 if ( dateTimeStr . Length >= XsdDateTimeFormat3F . Length
8086 && dateTimeStr . Length <= XsdDateTimeFormat . Length
81- && dateTimeStr . EndsWith ( "Z" ) )
87+ && dateTimeStr . EndsWith ( XsdUtcSuffix ) )
8288 {
8389#if NETFX_CORE
8490 var dateTimeType = JsConfig . DateHandler != JsonDateHandler . ISO8601
@@ -91,7 +97,7 @@ public static DateTime ParseShortestXsdDateTime(string dateTimeStr)
9197 if ( dateTime != null )
9298 return dateTime . Value ;
9399
94- return XmlConvert . ToDateTime ( dateTimeStr , XmlDateTimeSerializationMode . Utc ) . Prepare ( ) ;
100+ return XmlConvert . ToDateTime ( dateTimeStr , XmlDateTimeSerializationMode . Utc ) . Prepare ( parsedAsUtc : true ) ;
95101#endif
96102 }
97103
@@ -109,13 +115,30 @@ public static DateTime ParseShortestXsdDateTime(string dateTimeStr)
109115 }
110116 }
111117
118+ /// <summary>
119+ /// Repairs an out-of-spec XML date/time string which incorrectly uses a space instead of a 'T' to separate the date from the time.
120+ /// These string are occasionally generated by SQLite and can cause errors in OrmLite when reading these columns from the DB.
121+ /// </summary>
122+ /// <param name="dateTimeStr">The XML date/time string to repair</param>
123+ /// <returns>The repaired string. If no repairs were made, the original string is returned.</returns>
124+ private static string RepairXsdTimeSeparator ( string dateTimeStr )
125+ {
126+ if ( ( dateTimeStr . Length > XsdTimeSeparatorIndex ) && ( dateTimeStr [ XsdTimeSeparatorIndex ] == ' ' ) && dateTimeStr . EndsWith ( XsdUtcSuffix ) )
127+ {
128+ dateTimeStr = dateTimeStr . Substring ( 0 , XsdTimeSeparatorIndex ) + XsdTimeSeparator +
129+ dateTimeStr . Substring ( XsdTimeSeparatorIndex + 1 ) ;
130+ }
131+
132+ return dateTimeStr ;
133+ }
134+
112135 public static DateTime ? ParseManual ( string dateTimeStr )
113136 {
114137 if ( dateTimeStr == null || dateTimeStr . Length < "YYYY-MM-DD" . Length )
115138 return null ;
116139
117140 var dateKind = DateTimeKind . Utc ;
118- if ( dateTimeStr . EndsWith ( "Z" ) )
141+ if ( dateTimeStr . EndsWith ( XsdUtcSuffix ) )
119142 {
120143 dateTimeStr = dateTimeStr . Substring ( 0 , dateTimeStr . Length - 1 ) ;
121144 }
@@ -224,7 +247,7 @@ public static DateTimeOffset ParseDateTimeOffset(string dateTimeOffsetStr)
224247 // assume utc when no offset specified
225248 if ( dateTimeOffsetStr . LastIndexOfAny ( TimeZoneChars ) < 10 )
226249 {
227- if ( ! dateTimeOffsetStr . EndsWith ( "Z" ) ) dateTimeOffsetStr += "Z" ;
250+ if ( ! dateTimeOffsetStr . EndsWith ( XsdUtcSuffix ) ) dateTimeOffsetStr += XsdUtcSuffix ;
228251#if __MonoCS__
229252 // Without that Mono uses a Local timezone))
230253 dateTimeOffsetStr = dateTimeOffsetStr . Substring ( 0 , dateTimeOffsetStr . Length - 1 ) + "+00:00" ;
@@ -267,6 +290,8 @@ public static string ToXsdTimeSpanString(TimeSpan? timeSpan)
267290
268291 public static DateTime ParseXsdDateTime ( string dateTimeStr )
269292 {
293+ dateTimeStr = RepairXsdTimeSeparator ( dateTimeStr ) ;
294+
270295#if NETFX_CORE
271296 return XmlConvert . ToDateTimeOffset ( dateTimeStr ) . DateTime ;
272297#else
0 commit comments