Wrestling All Day With WebAPI, NewtonSoft and JSON Date Formats

 

Half to document what I now believe and half to share my findings, I’m going to do a short post that shows the implications of changing the DateTimeKind parameter of a DateTime field in a WebAPI controller.  That is, a WebAPI controller can return it’s results as JSON and the data that is DateTime gets converted based on some rules that for me were not clear.

First, let me state my conclusion (for those with short attention spans), then I’ll show the data and include the visual studio 2012 project I used to make this.

DateTimeKind.Local 013-10-05T13:00:00-07:00 (Has Timezone)
DateTimeKind.Utc 2013-10-05T13:00:00Z (Has Z)
DateTimeKind.Unspecifed 2013-10-05T13:00:00 No Timezone or Z
Not specified (default) 2013-10-05T13:00:00 No Timezone or Z

 

In my case, if I left unspecified (or default) I get no timezone which my JavaScript library (SenchaTouch) seems to believe is UTC.  That throws my times off by 7 hours!

Just to be more clear, here is what I have for my WebAPI Controller:

public class DateTestRecord
{

    public string MessageString { get; set; }
    public DateTime DateTimeRightNow { get; set; }
    public DateTime DateTime1PmOctober5Th2013 { get; set; }
}



public class DateTestController : ApiController
{

    public class LogEntry
    {
        public string Details { get; set; }
        public DateTime LogDate { get; set; }
    }

    // POST api/<controller>
    public HttpResponseMessage Get()
    {
        return Request.CreateResponse(HttpStatusCode.OK, new
            {
                data = new List<DateTestRecord>()
                    {
                        new DateTestRecord
                            {
                                MessageString = "First Line",
                                DateTime1PmOctober5Th2013 = new DateTime(2013, 10, 5, 13, 0, 0,DateTimeKind.Local),
                                DateTimeRightNow = DateTime.Now
                            },
                        new DateTestRecord
                            {
                                MessageString = "Second Line",
                                DateTime1PmOctober5Th2013 = new DateTime(2013, 10, 5, 13, 0, 0,DateTimeKind.Utc),
                                DateTimeRightNow = DateTime.Now
                            },
                        new DateTestRecord
                            {
                                MessageString = "Third Line",
                                DateTime1PmOctober5Th2013 = new DateTime(2013, 10, 5, 13, 0, 0,DateTimeKind.Unspecified),
                                DateTimeRightNow = DateTime.Now
                            },
                                new DateTestRecord
                            {
                                MessageString = "Third Line",
                                DateTime1PmOctober5Th2013 = new DateTime(2013, 10, 5, 13, 0, 0),
                                DateTimeRightNow = DateTime.Now
                            }
                    },
                success = true,
                message = "All Good"
            });
    }
}

The results of when I run this are as follows:

image

About Peter Kellner

Peter is a software professional specializing in mobile and web technologies. He has also been a Microsoft MVP for the past 7 years. To read more about Peter Kellner and his experience click here. For information about how Peter Kellner might be able to help you with your project click here.

Follow me:


Comments

  1. Peter Kellner says:

    BTW, Rick, you need to start a caption contest for your avatar :)

  2. Peter Kellner says:

    Geoff, I was thinking you probably had this problem nailed as I was trying to figure it out. I almost emailed you but I kept thinking I was 5 minutes from the answer. So, how do you handle in Ext? (I’m actually using SenchaTouch but it is likely the same). The “c” format fails miserably even though that is suppose to handle the iso format.

  3. Hi Peter,

    I’ll second the comments from Rick. ALL DateTime objects should use UTC during Json transport. There are several issues within Ext JS with how this is handled as well.

  4. Peter Kellner says:

    Hi Rick,
    Good advice. I could stick with the the “Z” format. what me wasting so much time was not realizing how the Z comes and goes (which I now know). It was not clear to me from the iso spec what no Z means. I think Sencha thinking it means UTC might be a reasonable assumption.

  5. Peter,

    For date formats I would suggest always shooting for the same format that the JavaScript JSON serializers produce which is:

    “2013-05-22T22:05:29.454Z”

    So I think given your map above that’s the DateTimeKind.Utc (which should be the default, but now see that it’s actually not (didn’t notice).

    Then again, I haven’t had a problem with this either. I think that clients should understand the “2013-05-22T12:07:17.4823957-10:00″ as well, which is explicit about specifying the timezone, so whatever date conversion can pick up this time zone value optionally… The date specified is UTC and the offset is calculated off this – looks like Sencha is throwing out the offset which is bad.

    In your case the easy solution is to just explicitly use the JSON configuration to explicitly use UTC for the format most likely.

Your Comments

*

Protected with IP Blacklist CloudIP Blacklist Cloud

Follow

Get every new post delivered to your Inbox

Join other followers: