-Added support for DateFormatString when reading JSON
This commit is contained in:
@@ -75,4 +75,4 @@ using System.Security;
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("6.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("6.0.2.17225")]
|
||||
[assembly: AssemblyFileVersion("6.0.2.17226")]
|
||||
|
||||
@@ -7818,5 +7818,76 @@ Parameter name: value",
|
||||
|
||||
Assert.AreEqual(originalUri, uriWithPlus2.OriginalString);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DateFormatStringWithDateTime()
|
||||
{
|
||||
DateTime dt = new DateTime(2000, 12, 22);
|
||||
string dateFormatString = "yyyy'-pie-'MMM'-'dddd'-'dd";
|
||||
JsonSerializerSettings settings = new JsonSerializerSettings
|
||||
{
|
||||
DateFormatString = dateFormatString
|
||||
};
|
||||
|
||||
string json = JsonConvert.SerializeObject(dt, settings);
|
||||
|
||||
Assert.AreEqual(@"""2000-pie-Dec-Friday-22""", json);
|
||||
|
||||
DateTime dt1 = JsonConvert.DeserializeObject<DateTime>(json, settings);
|
||||
|
||||
Assert.AreEqual(dt, dt1);
|
||||
|
||||
JsonTextReader reader = new JsonTextReader(new StringReader(json))
|
||||
{
|
||||
DateFormatString = dateFormatString
|
||||
};
|
||||
JValue v = (JValue)JToken.ReadFrom(reader);
|
||||
|
||||
Assert.AreEqual(JTokenType.Date, v.Type);
|
||||
Assert.AreEqual(typeof(DateTime), v.Value.GetType());
|
||||
Assert.AreEqual(dt, (DateTime)v.Value);
|
||||
|
||||
reader = new JsonTextReader(new StringReader(@"""abc"""))
|
||||
{
|
||||
DateFormatString = dateFormatString
|
||||
};
|
||||
v = (JValue)JToken.ReadFrom(reader);
|
||||
|
||||
Assert.AreEqual(JTokenType.String, v.Type);
|
||||
Assert.AreEqual(typeof(string), v.Value.GetType());
|
||||
Assert.AreEqual("abc", v.Value);
|
||||
}
|
||||
|
||||
#if !NET20
|
||||
[Test]
|
||||
public void DateFormatStringWithDateTimeOffset()
|
||||
{
|
||||
DateTimeOffset dt = new DateTimeOffset(new DateTime(2000, 12, 22));
|
||||
string dateFormatString = "yyyy'-pie-'MMM'-'dddd'-'dd";
|
||||
JsonSerializerSettings settings = new JsonSerializerSettings
|
||||
{
|
||||
DateFormatString = dateFormatString
|
||||
};
|
||||
|
||||
string json = JsonConvert.SerializeObject(dt, settings);
|
||||
|
||||
Assert.AreEqual(@"""2000-pie-Dec-Friday-22""", json);
|
||||
|
||||
DateTimeOffset dt1 = JsonConvert.DeserializeObject<DateTimeOffset>(json, settings);
|
||||
|
||||
Assert.AreEqual(dt, dt1);
|
||||
|
||||
JsonTextReader reader = new JsonTextReader(new StringReader(json))
|
||||
{
|
||||
DateFormatString = dateFormatString,
|
||||
DateParseHandling = DateParseHandling.DateTimeOffset
|
||||
};
|
||||
JValue v = (JValue)JToken.ReadFrom(reader);
|
||||
|
||||
Assert.AreEqual(JTokenType.Date, v.Type);
|
||||
Assert.AreEqual(typeof(DateTimeOffset), v.Value.GetType());
|
||||
Assert.AreEqual(dt, (DateTimeOffset)v.Value);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -127,6 +127,7 @@ namespace Newtonsoft.Json
|
||||
private bool _hasExceededMaxDepth;
|
||||
internal DateParseHandling _dateParseHandling;
|
||||
internal FloatParseHandling _floatParseHandling;
|
||||
private string _dateFormatString;
|
||||
private readonly List<JsonPosition> _stack;
|
||||
|
||||
/// <summary>
|
||||
@@ -193,6 +194,15 @@ namespace Newtonsoft.Json
|
||||
set { _floatParseHandling = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get or set how custom date formatted strings are parsed when reading JSON.
|
||||
/// </summary>
|
||||
public string DateFormatString
|
||||
{
|
||||
get { return _dateFormatString; }
|
||||
set { _dateFormatString = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a <see cref="JsonReaderException"/>.
|
||||
/// </summary>
|
||||
@@ -440,7 +450,7 @@ namespace Newtonsoft.Json
|
||||
}
|
||||
|
||||
object temp;
|
||||
if (DateTimeUtils.TryParseDateTime(s, DateParseHandling.DateTimeOffset, DateTimeZoneHandling, out temp))
|
||||
if (DateTimeUtils.TryParseDateTime(s, DateParseHandling.DateTimeOffset, DateTimeZoneHandling, _dateFormatString, Culture, out temp))
|
||||
{
|
||||
dt = (DateTimeOffset)temp;
|
||||
SetToken(JsonToken.Date, dt, false);
|
||||
@@ -728,7 +738,7 @@ namespace Newtonsoft.Json
|
||||
}
|
||||
|
||||
object temp;
|
||||
if (DateTimeUtils.TryParseDateTime(s, DateParseHandling.DateTime, DateTimeZoneHandling, out temp))
|
||||
if (DateTimeUtils.TryParseDateTime(s, DateParseHandling.DateTime, DateTimeZoneHandling, _dateFormatString, Culture, out temp))
|
||||
{
|
||||
dt = (DateTime)temp;
|
||||
dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
|
||||
|
||||
@@ -713,6 +713,13 @@ namespace Newtonsoft.Json
|
||||
reader.MaxDepth = _maxDepth;
|
||||
}
|
||||
|
||||
string previousDateFormatString = null;
|
||||
if (_dateFormatStringSet && reader.DateFormatString != _dateFormatString)
|
||||
{
|
||||
previousDateFormatString = reader.DateFormatString;
|
||||
reader.DateFormatString = _dateFormatString;
|
||||
}
|
||||
|
||||
TraceJsonReader traceJsonReader = (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
|
||||
? new TraceJsonReader(reader)
|
||||
: null;
|
||||
@@ -734,6 +741,8 @@ namespace Newtonsoft.Json
|
||||
reader.FloatParseHandling = previousFloatParseHandling.Value;
|
||||
if (_maxDepthSet)
|
||||
reader.MaxDepth = previousMaxDepth;
|
||||
if (_dateFormatStringSet)
|
||||
reader.DateFormatString = previousDateFormatString;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ namespace Newtonsoft.Json
|
||||
dateParseHandling = _dateParseHandling;
|
||||
|
||||
object dt;
|
||||
if (DateTimeUtils.TryParseDateTime(text, dateParseHandling, DateTimeZoneHandling, out dt))
|
||||
if (DateTimeUtils.TryParseDateTime(text, dateParseHandling, DateTimeZoneHandling, DateFormatString, Culture, out dt))
|
||||
{
|
||||
SetToken(JsonToken.Date, dt);
|
||||
return;
|
||||
|
||||
@@ -91,5 +91,5 @@ using System.Security;
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("6.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("6.0.2.17225")]
|
||||
[assembly: AssemblyFileVersion("6.0.2.17226")]
|
||||
[assembly: CLSCompliant(true)]
|
||||
|
||||
@@ -1121,28 +1121,35 @@ To fix this error either change the JSON to a {1} or change the deserialized typ
|
||||
object keyValue = reader.Value;
|
||||
if (CheckPropertyName(reader, keyValue.ToString()))
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
object dt;
|
||||
// this is for correctly reading ISO and MS formatted dictionary keys
|
||||
if ((keyTypeCode == PrimitiveTypeCode.DateTime || keyTypeCode == PrimitiveTypeCode.DateTimeNullable)
|
||||
&& DateTimeUtils.TryParseDateTime(keyValue.ToString(), DateParseHandling.DateTime, reader.DateTimeZoneHandling, out dt))
|
||||
DateParseHandling dateParseHandling;
|
||||
switch (keyTypeCode)
|
||||
{
|
||||
keyValue = dt;
|
||||
}
|
||||
case PrimitiveTypeCode.DateTime:
|
||||
case PrimitiveTypeCode.DateTimeNullable:
|
||||
dateParseHandling = DateParseHandling.DateTime;
|
||||
break;
|
||||
#if !NET20
|
||||
else if ((keyTypeCode == PrimitiveTypeCode.DateTimeOffset || keyTypeCode == PrimitiveTypeCode.DateTimeOffsetNullable)
|
||||
&& DateTimeUtils.TryParseDateTime(keyValue.ToString(), DateParseHandling.DateTimeOffset, reader.DateTimeZoneHandling, out dt))
|
||||
{
|
||||
keyValue = dt;
|
||||
}
|
||||
case PrimitiveTypeCode.DateTimeOffset:
|
||||
case PrimitiveTypeCode.DateTimeOffsetNullable:
|
||||
dateParseHandling = DateParseHandling.DateTimeOffset;
|
||||
break;
|
||||
#endif
|
||||
else
|
||||
{
|
||||
keyValue = EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType);
|
||||
default:
|
||||
dateParseHandling = DateParseHandling.None;
|
||||
break;
|
||||
}
|
||||
|
||||
// this is for correctly reading ISO and MS formatted dictionary keys
|
||||
object dt;
|
||||
if (dateParseHandling != DateParseHandling.None && DateTimeUtils.TryParseDateTime(keyValue.ToString(), dateParseHandling, reader.DateTimeZoneHandling, reader.DateFormatString, reader.Culture, out dt))
|
||||
keyValue = dt;
|
||||
else
|
||||
keyValue = EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -284,7 +284,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool TryParseDateTime(string s, DateParseHandling dateParseHandling, DateTimeZoneHandling dateTimeZoneHandling, out object dt)
|
||||
internal static bool TryParseDateTime(string s, DateParseHandling dateParseHandling, DateTimeZoneHandling dateTimeZoneHandling, string dateFormatString, CultureInfo culture, out object dt)
|
||||
{
|
||||
if (s.Length > 0)
|
||||
{
|
||||
@@ -292,12 +292,20 @@ namespace Newtonsoft.Json.Utilities
|
||||
{
|
||||
if (s.StartsWith("/Date(", StringComparison.Ordinal) && s.EndsWith(")/", StringComparison.Ordinal))
|
||||
{
|
||||
return TryParseDateMicrosoft(s, dateParseHandling, dateTimeZoneHandling, out dt);
|
||||
if (TryParseDateMicrosoft(s, dateParseHandling, dateTimeZoneHandling, out dt))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (s.Length >= 19 && s.Length <= 40 && char.IsDigit(s[0]) && s[10] == 'T')
|
||||
{
|
||||
return TryParseDateIso(s, dateParseHandling, dateTimeZoneHandling, out dt);
|
||||
if (TryParseDateIso(s, dateParseHandling, dateTimeZoneHandling, out dt))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(dateFormatString))
|
||||
{
|
||||
if (TryParseDateExact(s, dateParseHandling, dateTimeZoneHandling, dateFormatString, culture, out dt))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,6 +365,34 @@ namespace Newtonsoft.Json.Utilities
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryParseDateExact(string text, DateParseHandling dateParseHandling, DateTimeZoneHandling dateTimeZoneHandling, string dateFormatString, CultureInfo culture, out object dt)
|
||||
{
|
||||
#if !NET20
|
||||
if (dateParseHandling == DateParseHandling.DateTimeOffset)
|
||||
{
|
||||
DateTimeOffset temp;
|
||||
if (DateTimeOffset.TryParseExact(text, dateFormatString, culture, DateTimeStyles.RoundtripKind, out temp))
|
||||
{
|
||||
dt = temp;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
DateTime temp;
|
||||
if (DateTime.TryParseExact(text, dateFormatString, culture, DateTimeStyles.RoundtripKind, out temp))
|
||||
{
|
||||
temp = EnsureDateTime(temp, dateTimeZoneHandling);
|
||||
dt = temp;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
dt = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static TimeSpan ReadOffset(string offsetText)
|
||||
{
|
||||
bool negative = (offsetText[0] == '-');
|
||||
|
||||
Reference in New Issue
Block a user