From 42ee730f3a0f49fd1ece2ddf6619eed938be52a8 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Mon, 28 May 2018 20:54:01 +1200 Subject: [PATCH] Fix losing DateTime.Kind when deserializing ISO date strings (#1727) --- Src/Newtonsoft.Json.Tests/Issues/Issue1708.cs | 63 +++++++++++++++++++ .../JsonSerializerInternalReader.cs | 12 +++- 2 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 Src/Newtonsoft.Json.Tests/Issues/Issue1708.cs diff --git a/Src/Newtonsoft.Json.Tests/Issues/Issue1708.cs b/Src/Newtonsoft.Json.Tests/Issues/Issue1708.cs new file mode 100644 index 00000000..a768b2b9 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/Issues/Issue1708.cs @@ -0,0 +1,63 @@ +#region License +// Copyright (c) 2007 James Newton-King +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.Serialization; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; +using Newtonsoft.Json.Utilities; +#if DNXCORE50 +using Xunit; +using Test = Xunit.FactAttribute; +using Assert = Newtonsoft.Json.Tests.XUnitAssert; +#else +using NUnit.Framework; +#endif + +namespace Newtonsoft.Json.Tests.Issues +{ + [TestFixture] + public class Issue1708 : TestFixtureBase + { + [Test] + public void Test_DateTime() + { + JsonTextReader jsonTextReader = new JsonTextReader(new StringReader("'2018-05-27T23:25:08Z'")); + jsonTextReader.DateParseHandling = DateParseHandling.None; + jsonTextReader.Read(); + + JsonSerializer serializer = new JsonSerializer(); + DateTime dt = serializer.Deserialize(jsonTextReader); + + Assert.AreEqual(DateTimeKind.Utc, dt.Kind); + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs index 12d53453..db86415c 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs @@ -953,15 +953,23 @@ namespace Newtonsoft.Json.Serialization if (contract.IsEnum) { - if (value is string) + if (value is string s) { - return EnumUtils.ParseEnum(contract.NonNullableUnderlyingType, value.ToString(), false); + return EnumUtils.ParseEnum(contract.NonNullableUnderlyingType, s, false); } if (ConvertUtils.IsInteger(primitiveContract.TypeCode)) { return Enum.ToObject(contract.NonNullableUnderlyingType, value); } } + else if (contract.NonNullableUnderlyingType == typeof(DateTime)) + { + // use DateTimeUtils because Convert.ChangeType does not set DateTime.Kind correctly + if (value is string s && DateTimeUtils.TryParseDateTime(s, reader.DateTimeZoneHandling, reader.DateFormatString, reader.Culture, out DateTime dt)) + { + return DateTimeUtils.EnsureDateTime(dt, reader.DateTimeZoneHandling); + } + } #if HAVE_BIG_INTEGER if (value is BigInteger integer)