The type you're deserializing into should match the data you are expecting. If you're not expecting an offset to be included, then don't deserialize into a DateTimeOffset
. Instead, deserialize to a DateTime
. It will have DateTimeKind.Unspecified
for its .Kind
property.
The knowledge you have about the web server's time zone is extraneous to the task of deserialization. So apply it separately, after-the-fact.
// 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));
Update
Per comments, if you need to do this conversion in the manner you've requested, you'll need a custom json converter. This should do the trick:
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);
}
}
Then you can wire it up during conversion:
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);
Be sure to used a valid time zone id. Do not use a fixed offset.
Also, this will not be the correct approach if you are trying to pass a time without a date. That is a completely different problem, and passing in 0001-01-01
for the date is not a great approach. I'll be happy to discuss with you in chat.