@@ -21,6 +21,7 @@ namespace ServiceStack.Text.Common
21
21
{
22
22
public static class DateTimeSerializer
23
23
{
24
+ public const string CondensedDateTimeFormat = "yyyyMMdd" ; //8
24
25
public const string ShortDateTimeFormat = "yyyy-MM-dd" ; //11
25
26
public const string DefaultDateTimeFormat = "dd/MM/yyyy HH:mm:ss" ; //20
26
27
public const string DefaultDateTimeFormatWithFraction = "dd/MM/yyyy HH:mm:ss.fff" ; //24
@@ -40,6 +41,9 @@ public static class DateTimeSerializer
40
41
private const char XsdTimeSeparator = 'T' ;
41
42
private static readonly int XsdTimeSeparatorIndex = XsdDateTimeFormat . IndexOf ( XsdTimeSeparator ) ;
42
43
private const string XsdUtcSuffix = "Z" ;
44
+ private static readonly char [ ] DateTimeSeperators = new [ ] { '-' , '/' } ;
45
+
46
+ public static Func < string , Exception , DateTime > OnParseErrorFn { get ; set ; }
43
47
44
48
/// <summary>
45
49
/// If AlwaysUseUtc is set to true then convert all DateTime to UTC.
@@ -70,69 +74,84 @@ public static DateTime ParseRFC1123DateTime(string dateTimeStr)
70
74
71
75
public static DateTime ParseShortestXsdDateTime ( string dateTimeStr )
72
76
{
73
- if ( string . IsNullOrEmpty ( dateTimeStr ) )
74
- return DateTime . MinValue ;
77
+ try
78
+ {
79
+ if ( string . IsNullOrEmpty ( dateTimeStr ) )
80
+ return DateTime . MinValue ;
75
81
76
- if ( dateTimeStr . StartsWith ( EscapedWcfJsonPrefix , StringComparison . Ordinal ) || dateTimeStr . StartsWith ( WcfJsonPrefix , StringComparison . Ordinal ) )
77
- return ParseWcfJsonDate ( dateTimeStr ) . Prepare ( ) ;
82
+ if ( dateTimeStr . StartsWith ( EscapedWcfJsonPrefix , StringComparison . Ordinal ) || dateTimeStr . StartsWith ( WcfJsonPrefix , StringComparison . Ordinal ) )
83
+ return ParseWcfJsonDate ( dateTimeStr ) . Prepare ( ) ;
78
84
79
- if ( dateTimeStr . Length == DefaultDateTimeFormat . Length
80
- || dateTimeStr . Length == DefaultDateTimeFormatWithFraction . Length )
81
- {
82
- var unspecifiedDate = DateTime . Parse ( dateTimeStr , CultureInfo . InvariantCulture ) ;
83
- if ( JsConfig . AssumeUtc )
84
- unspecifiedDate = DateTime . SpecifyKind ( unspecifiedDate , DateTimeKind . Utc ) ;
85
+ if ( dateTimeStr . Length == DefaultDateTimeFormat . Length
86
+ || dateTimeStr . Length == DefaultDateTimeFormatWithFraction . Length )
87
+ {
88
+ var unspecifiedDate = DateTime . Parse ( dateTimeStr , CultureInfo . InvariantCulture ) ;
89
+ if ( JsConfig . AssumeUtc )
90
+ unspecifiedDate = DateTime . SpecifyKind ( unspecifiedDate , DateTimeKind . Utc ) ;
85
91
86
- return unspecifiedDate . Prepare ( ) ;
87
- }
92
+ return unspecifiedDate . Prepare ( ) ;
93
+ }
88
94
89
- switch ( JsConfig . DateHandler )
90
- {
91
- case DateHandler . UnixTime :
92
- int unixTime ;
93
- if ( int . TryParse ( dateTimeStr , out unixTime ) )
94
- return unixTime . FromUnixTime ( ) ;
95
- break ;
96
- case DateHandler . UnixTimeMs :
97
- long unixTimeMs ;
98
- if ( long . TryParse ( dateTimeStr , out unixTimeMs ) )
99
- return unixTimeMs . FromUnixTimeMs ( ) ;
100
- break ;
101
- }
95
+ switch ( JsConfig . DateHandler )
96
+ {
97
+ case DateHandler . UnixTime :
98
+ int unixTime ;
99
+ if ( int . TryParse ( dateTimeStr , out unixTime ) )
100
+ return unixTime . FromUnixTime ( ) ;
101
+ break ;
102
+ case DateHandler . UnixTimeMs :
103
+ long unixTimeMs ;
104
+ if ( long . TryParse ( dateTimeStr , out unixTimeMs ) )
105
+ return unixTimeMs . FromUnixTimeMs ( ) ;
106
+ break ;
107
+ }
102
108
103
- dateTimeStr = RepairXsdTimeSeparator ( dateTimeStr ) ;
109
+ dateTimeStr = RepairXsdTimeSeparator ( dateTimeStr ) ;
104
110
105
- if ( dateTimeStr . Length == XsdDateTimeFormatSeconds . Length )
106
- return DateTime . ParseExact ( dateTimeStr , XsdDateTimeFormatSeconds , null , DateTimeStyles . AdjustToUniversal ) . Prepare ( parsedAsUtc : true ) ;
111
+ if ( dateTimeStr . Length == XsdDateTimeFormatSeconds . Length )
112
+ return DateTime . ParseExact ( dateTimeStr , XsdDateTimeFormatSeconds , null , DateTimeStyles . AdjustToUniversal ) . Prepare ( parsedAsUtc : true ) ;
107
113
108
- if ( dateTimeStr . Length >= XsdDateTimeFormat3F . Length
109
- && dateTimeStr . Length <= XsdDateTimeFormat . Length
110
- && dateTimeStr . EndsWith ( XsdUtcSuffix ) )
111
- {
112
- var dateTime = Env . IsMono ? ParseManual ( dateTimeStr ) : null ;
113
- if ( dateTime != null )
114
- return dateTime . Value ;
114
+ if ( dateTimeStr . Length >= XsdDateTimeFormat3F . Length
115
+ && dateTimeStr . Length <= XsdDateTimeFormat . Length
116
+ && dateTimeStr . EndsWith ( XsdUtcSuffix ) )
117
+ {
118
+ var dateTime = Env . IsMono ? ParseManual ( dateTimeStr ) : null ;
119
+ if ( dateTime != null )
120
+ return dateTime . Value ;
115
121
116
- return PclExport . Instance . ParseXsdDateTimeAsUtc ( dateTimeStr ) ;
117
- }
122
+ return PclExport . Instance . ParseXsdDateTimeAsUtc ( dateTimeStr ) ;
123
+ }
118
124
119
- if ( dateTimeStr . Length == ShortDateTimeFormat . Length )
120
- {
121
- var manualDate = ParseManual ( dateTimeStr ) ;
122
- if ( manualDate != null )
123
- return manualDate . Value ;
124
- }
125
+ if ( dateTimeStr . Length == CondensedDateTimeFormat . Length && dateTimeStr . IndexOfAny ( DateTimeSeperators ) == - 1 )
126
+ {
127
+ return DateTime . ParseExact ( dateTimeStr , "yyyyMMdd" , CultureInfo . InvariantCulture , DateTimeStyles . None ) ;
128
+ }
125
129
126
- try
127
- {
128
- var dateTime = DateTime . Parse ( dateTimeStr , null , DateTimeStyles . AssumeLocal ) ;
129
- return dateTime . Prepare ( ) ;
130
+ if ( dateTimeStr . Length == ShortDateTimeFormat . Length )
131
+ {
132
+ var manualDate = ParseManual ( dateTimeStr ) ;
133
+ if ( manualDate != null )
134
+ return manualDate . Value ;
135
+ }
136
+
137
+ try
138
+ {
139
+ var dateTime = DateTime . Parse ( dateTimeStr , null , DateTimeStyles . AssumeLocal ) ;
140
+ return dateTime . Prepare ( ) ;
141
+ }
142
+ catch ( FormatException )
143
+ {
144
+ var manualDate = ParseManual ( dateTimeStr ) ;
145
+ if ( manualDate != null )
146
+ return manualDate . Value ;
147
+
148
+ throw ;
149
+ }
130
150
}
131
- catch ( FormatException )
151
+ catch ( Exception ex )
132
152
{
133
- var manualDate = ParseManual ( dateTimeStr ) ;
134
- if ( manualDate != null )
135
- return manualDate . Value ;
153
+ if ( OnParseErrorFn != null )
154
+ return OnParseErrorFn ( dateTimeStr , ex ) ;
136
155
137
156
throw ;
138
157
}
0 commit comments