How to add timezone offset to JSON.NET serialization?

后端 未结 2 1382
天命终不由人
天命终不由人 2020-12-09 05:38

My DateTimePicker is bound to property:

    picker.DataBindings.Add(\"Value\", this, \"EventDate\");
    ...
    private DateTime eventDate;
    public DateT         


        
相关标签:
2条回答
  • 2020-12-09 06:07

    Have you tried type DateTimeOffset instead of DateTime? This is the type with timezone information.

    var example = new
    {
        Now = DateTimeOffset.Now,
        UtcNow = DateTimeOffset.UtcNow,
        Sometime = new DateTimeOffset(2014, 10, 11, 1, 4, 9, new TimeSpan(8, 0, 0)),
        FromDateTime = new DateTimeOffset(new DateTime(2010, 1, 1)),
    };
    string json = JsonConvert.SerializeObject(example, Formatting.Indented);
    Console.WriteLine(json);
    

    Gives me:

    {
      "Now": "2014-08-03T22:08:47.8127753+08:00",
      "UtcNow": "2014-08-03T14:08:47.8137754+00:00",
      "Sometime": "2014-10-11T01:04:09+08:00",
      "FromDateTime": "2010-01-01T00:00:00+08:00"
    }
    

    EDIT - Alternative way

    You noticed that DateTime.Now has timezone offset in JSON while manually created DateTime does not. This is because DateTime.Now has Kind equal to DateTimeKind.Local while the other has DateTimeKind.Unspecified, and JSON.NET just handles them differently.

    So the alternative way is:

    var product2 = new
    {
        Now = DateTime.Now,
        Sometime = new DateTime(2014, 10, 11, 0, 0, 0),
        SometimeLocal = new DateTime(2014, 10, 11, 0, 0, 0, DateTimeKind.Local),
        SometimeUtc = new DateTime(2014, 10, 11, 0, 0, 0, DateTimeKind.Utc)
    };
    
    string json2 = JsonConvert.SerializeObject(product2, Formatting.Indented);
    
    Console.WriteLine(json2);
    

    Which outputs:

    {
      "Now": "2014-08-03T23:39:45.3319275+08:00",
      "Sometime": "2014-10-11T00:00:00",
      "SometimeLocal": "2014-10-11T00:00:00+08:00",
      "SometimeUtc": "2014-10-11T00:00:00Z"
    }
    

    EDIT2 - For data binding

    OK you use data binding. Then you can update your setter to convert automatically:

    picker.DataBindings.Add("Value", this, "EventDate");
    ...
    private DateTimeOffset eventDate;
    public DateTime EventDate
    {
        get { return eventDate.LocalDateTime; }
        set { eventDate = new DateTimeOffset(value); }
    }
    

    Then you can use eventDate to serialize to JSON.

    Or to set Kind:

    picker.DataBindings.Add("Value", this, "EventDate");
    ...
    private DateTime eventDate;
    public DateTime EventDate
    {
        get { return eventDate; }
        set
        {
            // Create a copy of DateTime and set Kind to Local since Kind is readonly
            eventDate = new DateTime(value.Ticks, DateTimeKind.Local);
        }
    }
    

    Both should work.

    0 讨论(0)
  • 2020-12-09 06:23

    I use this.

    It works very well.

    JsonConvert.SerializeObject(object, new JsonSerializerSettings()
    {
        DateFormatHandling = DateFormatHandling.IsoDateFormat,
        DateTimeZoneHandling = DateTimeZoneHandling.Local
    });
    
    0 讨论(0)
提交回复
热议问题