以下声明打印" 1/1/0001 4:00:00 PM -05:00"
Console.WriteLine(JsonConvert.DeserializeObject<DateTimeOffset>("\"0001-01-01T16:00:00\""));
这是因为当json.net将DateTime字符串(没有偏移量)反序列化为DateTimeOffset对象时,它会分配本地偏移量,在本例中为-05:00。
如果我不想使用本地偏移怎么办?有什么方法可以指定用于此反序列化的偏移量吗?
(用例是数据库服务器,Web服务器位于不同的时区,我需要具有区域未指定时间的传入请求,以便在反序列化后使数据库服务器偏移。)
更新:我无法控制传入时间字符串的格式。我有一个数据传输对象类,它具有DateTimeOffset属性,我需要将传入的时间数据存储到此属性。
答案 0 :(得分:5)
您要反序列化的类型应与您期望的数据匹配。如果您不希望包含偏移量,则不要反序列化为DateTimeOffset
。相反,反序列化为DateTime
。它的DateTimeKind.Unspecified
属性将为.Kind
。
您对Web服务器时区的了解与反序列化任务无关。因此,事后再单独应用它。
// deserialize the json
DateTime dt = JsonConvert.DeserializeObject<DateTime>("\"2014-01-01T00:00:00\"");
// find your target time zone
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
// apply the time zone to determine the offset, and create the DateTimeOffset
DateTimeOffset dto = new DateTimeOffset(dt, tz.GetUtcOffset(dt));
<强>更新强>
根据评论,如果您需要以您请求的方式进行此转换,则需要自定义json转换器。这应该可以解决问题:
public class CustomDateTimeConverter : IsoDateTimeConverter
{
private readonly string defaultTimeZoneId;
public CustomDateTimeConverter(string defaultTimeZoneId)
{
this.defaultTimeZoneId = defaultTimeZoneId;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (objectType != typeof (DateTimeOffset) && objectType != typeof (DateTimeOffset?))
return base.ReadJson(reader, objectType, existingValue, serializer);
var dateText = reader.Value.ToString();
if (objectType == typeof(DateTimeOffset?) && string.IsNullOrEmpty(dateText))
return null;
if (dateText.IndexOfAny(new[] { 'Z', 'z', '+'}) == -1 && dateText.Count(c => c == '-') == 2)
{
var dt = DateTime.Parse(dateText);
var tz = TimeZoneInfo.FindSystemTimeZoneById(this.defaultTimeZoneId);
var offset = tz.GetUtcOffset(dt);
return new DateTimeOffset(dt, offset);
}
return DateTimeOffset.Parse(dateText);
}
}
然后你可以在转换期间连接它:
var settings = new JsonSerializerSettings();
settings.DateParseHandling = DateParseHandling.None;
settings.Converters.Add(new CustomDateTimeConverter(defaultTimeZoneId: "Eastern Standard Time"));
DateTimeOffset dto = JsonConvert.DeserializeObject<DateTimeOffset>("\"2014-01-01T00:00:00\"", settings);
请务必使用有效的时区ID。不要使用固定的偏移量。
此外,如果您尝试通过没有约会的时间,这将不是正确的方法。这是一个完全不同的问题,并且传递0001-01-01
日期并不是一个好方法。我很乐意与您讨论in chat。
答案 1 :(得分:0)
如果您在原始字符串(-8:00)中有偏移量:
Console.WriteLine(JsonConvert.DeserializeObject<DateTimeOffset>("\"0001-01-01T16:00:00-08:00\""));
如果没有,试试这个
var dateTime = JsonConvert.DeserializeObject<DateTime>("\"0001-01-01T16:00:00\"");
DateTimeOffset dto = new DateTimeOffset(dateTime, TimeSpan.FromHours(-8));