В обычном .net, Если у нас есть время, которое имеет DateTimeKind.Unspecified Если мы преобразуем ToLocal - предполагается, что дата ввода - это UTC при преобразовании. Если мы конвертируем ToUniversal - предполагается, что дата ввода является локальной при преобразованииjson.net Сериализация/десериализация datetime 'unspecified'
Однако, если наша строка date в JSON.Net не указана, она, похоже, не имеет такой логики? Посмотрите на мои тестовые примеры ниже - я что-то делаю неправильно? Или это по дизайну? или ошибка в JSON.Net? Спасибо!
// TODO: This Fails with output
// date string: "2014-06-02T21:00:00.0000000"
// date serialized: 2014-06-02T21:00:00.0000000Z
// Expected date and time to be <2014-06-03 04:00:00>, but found <2014-06-02 21:00:00>.
[TestMethod]
public void NEW_Should_deserialize_unspecified_datestring_to_utc_date()
{
string dateString = "\"2014-06-02T21:00:00.0000000\"";
DateTime dateRaw = new DateTime(2014, 6, 2, 21, 0, 0, 0, DateTimeKind.Unspecified);
DateTime dateRawAsUtc = new DateTime(2014, 6, 3, 4, 0, 0, 0, DateTimeKind.Utc);
dateRawAsUtc.Should().Be(dateRaw.ToUniversalTime());
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
settings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
DateTime dateSerialized = JsonConvert.DeserializeObject<DateTime>(dateString, settings);
Console.WriteLine("date string: " + dateString);
Console.WriteLine("date serialized: " + dateSerialized.ToString("o"));
dateSerialized.Kind.Should().Be(DateTimeKind.Utc);
dateSerialized.Should().Be(dateRaw.ToUniversalTime());
dateSerialized.Should().Be(dateRawAsUtc);
}
// TODO: This Fails with output
// date string: "2014-06-02T21:00:00.0000000"
// date serialized: 2014-06-02T21:00:00.0000000-07:00
// Expected date and time to be <2014-06-02 14:00:00>, but found <2014-06-02 21:00:00>.
[TestMethod]
public void NEW_Should_deserialize_unspecified_datestring_to_local_date()
{
string dateString = "\"2014-06-02T21:00:00.0000000\"";
DateTime dateRaw = new DateTime(2014, 6, 2, 21, 0, 0, 0, DateTimeKind.Unspecified);
DateTime dateRawAsLocal = new DateTime(2014, 6, 2, 14, 0, 0, 0, DateTimeKind.Local);
dateRawAsLocal.Should().Be(dateRaw.ToLocalTime());
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
settings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
DateTime dateSerialized = JsonConvert.DeserializeObject<DateTime>(dateString, settings);
Console.WriteLine("date string: " + dateString);
Console.WriteLine("date serialized: " + dateSerialized.ToString("o"));
dateSerialized.Kind.Should().Be(DateTimeKind.Local);
dateSerialized.Should().Be(dateRaw.ToLocalTime());
dateSerialized.Should().Be(dateRawAsLocal);
}
[TestMethod]
public void NEW_Should_deserialize_unspecified_datestring_to_unspecified_date()
{
string dateString = "\"2014-06-02T21:00:00.0000000\""; // unspecified, does not have the 'Z'
DateTime dateRaw = new DateTime(2014, 6, 2, 21, 0, 0, 0, DateTimeKind.Unspecified);
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.DateTimeZoneHandling = DateTimeZoneHandling.Unspecified;
settings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
DateTime dateSerialized = JsonConvert.DeserializeObject<DateTime>(dateString, settings);
Console.WriteLine("date string: " + dateString);
Console.WriteLine("date serialized: " + dateSerialized.ToString("o"));
dateSerialized.Kind.Should().Be(DateTimeKind.Unspecified);
dateSerialized.Should().Be(dateRaw);
}
Попробуйте использовать 'DateTimeOffset' вместо 'DateTime'. Он должен десериализоваться правильно. – daramasala