#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2009
    Posts
    151
    Rep Power
    19

    Setting Date Format


    I've created a database first MVC 5 application. I setup a very simple controller method to retrieve data and pass it on as JSON.
    Code:
            // GET JSON Calendar view        
            public ActionResult calendarJson()
            {
                var calendarJson = db.reservations;            
    
                return Json(calendarJson, JsonRequestBehavior.AllowGet);
            }
    The problem is the date format i end up passing back in JSON is "/Date(1499054400000)/". This is my first time using c#/.NET. I don't have a class setup for my model because i added an ADO.NET data entity model to scaffold the project from the database. My Modes folder appears to be empty.

    I guess my question is where and how do i format this?

    Thanks,
    DSFX

    Edit: typos
    Last edited by dsfx; July 22nd, 2017 at 01:23 PM.
  2. #2
  3. Lazy Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    16,436
    Rep Power
    9645
    Wow, they're on MVC 5 now? I swear 3 was still new not that long ago...

    JSON doesn't actually have a way to represent dates natively, which is why Microsoft came up with that "/Date(...)/" format. You can change how your dates are serialized (would be nice...) but you will need to alter your Javascript anyways.

    What's your Javascript now?
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2009
    Posts
    151
    Rep Power
    19
    My JavaScript is fairly simple right now, i was trying to work this date thing out. Big picture i've got fullcalendar and i'm trying to populate it.

    Code:
    //get the calendar content and populate it
        $.ajax({
            url: "/reservations/calendarJson",
            success: function (result) {
    
                //var result = JSON.parse(result);            
                console.log(result);
    
                // try to convert a date to date object.
                var d = new Date(result[0].calendarDate);
    
                console.log("Date format: " +d);
    
            }
        }).done(function () {
            console.log("ajax call compete")
        });
    The result i get from this is an "Invalid Date"

    I've got a side question. In my database the date is reading as "2017-07-03 12:00:00 AM" but after i query it the result i get is "/Date(1499054400000)/". I don't see how that string of numbers corresponds to the stored date at all. Thanks for your help.
  6. #4
  7. Lazy Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    16,436
    Rep Power
    9645
    1499054400 is the number of seconds since January 1, 1970 (which .NET represents in milliseconds). It's a fairly standard way of representing a time in computing.

    Javascript's Date() can take that number (also in milliseconds). Throw in a regular expression that extracts the number from the string and you get
    javascript Code:
    var d = new Date(parseInt(result[0].calendarDate.match(/\d+/)[0]));


    But going back to changing your serialization: that would be even better, and you wouldn't have to change your Javascript after all. Take a look at the discussion here.
    Last edited by requinix; July 22nd, 2017 at 01:46 PM.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2009
    Posts
    151
    Rep Power
    19
    Thanks so much. I've implemented the JS solution for now just to get it working so i have something to show Monday haha but i believe this type of thing should be handled in the controller.

    JS for the sake of it:
    Code:
                 for (var key in result) {
                    console.log("before: " + result[key].calendarDate);
                    result[key].calendarDate = new Date(ToJavaScriptDate(result[key].calendarDate));
                    console.log("after: " + result[key].calendarDate);
                }
    
    
    function ToJavaScriptDate(value) {
        var pattern = /Date\(([^)]+)\)/;
        var results = pattern.exec(value);
        var dt = new Date(parseFloat(results[1]));
        return (dt.getMonth() + 1) + "/" + dt.getDate() + "/" + dt.getFullYear();
    }

    Now i did see there was some c# in the post you linked. I would run this in my controller, format the dates then pass the object along, correct?
    Code:
    var parsed = JSON.parse(data, function(key, value) {
      if (typeof value === 'string') {
        var d = /\/Date\((\d*)\)\//.exec(value);
        return (d) ? new Date(+d[1]) : value;
      }
      return value;
    });
    I think I've got this now. Thanks for all the help.
  10. #6
  11. Lazy Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    16,436
    Rep Power
    9645
    You might as well put the "new Date" part into ToJavaScriptDate() too.


    That SO link mentioned the same two methods I said: modify your C# to return a date string (like Y-M-D H:M:S) so you can just "new Date(value)" without the conversion process, or keep the "/Date(...)/" format that's native to .NET and use Javascript to parse it.
    The first method would be nicer because that removes the .NET "dependency" from the JSON - it would be a regular date string anyone can understand. But it involves modifying how your .NET objects are being serialized into JSON format, meaning you'd have to do some work in your C#.
    The second method is what you now have.

    That JSON.parse() stuff is possible but not quite compatible with your current code. You're using jQuery to do the AJAX call, and that decodes (calls JSON.parse) the response automatically. jQuery also does not give you a way to specify a reviver during the decoding process.
    You have three options that are all equally valid:
    a) The code you have now that calls ToJavaScriptDate.
    b) Telling .ajax() that it should process the response as text (dataType:"text") and doing the JSON.parse() step manually.
    c) Using the "converters" option to .ajax() which lets you give a callback function to decode the response.

    (b) and (c) are essentially the same thing approached two ways.
    javascript Code:
    $.ajax({
        url: "/reservations/calendarJson",
        dataType: "text",
        success: function (result) {
     
            // reviver in here
            var result = JSON.parse(result, function(key, value) {
                if (typeof value === 'string') {
                    var d = /\/Date\((\d*)\)\//.exec(value);
                    return (d) ? new Date(+d[1]) : value;
                }
                return value;
            });
            console.log(result);
     
            // result[0].calendarDate is already a Date object
        }
    }).done(function () {
        console.log("ajax call compete")
    });

    javascript Code:
    $.ajax({
        url: "/reservations/calendarJson",
        converters: { "* text": function(result) {
            // reviver in here
            return JSON.parse(result, function(key, value) {
                if (typeof value === 'string') {
                    var d = /\/Date\((\d*)\)\//.exec(value);
                    return (d) ? new Date(+d[1]) : value;
                }
                return value;
            });
        } },
        success: function (result) {
            console.log(result);
        }
    }).done(function () {
        console.log("ajax call compete")
    });
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2009
    Posts
    151
    Rep Power
    19
    You are correct and I have moved the "new date" into the ToJavaScriptDate function. Thank you for pointing that out. You are also right you did mention both those methods, I'm in day 3 of my c#/.Net learning blitz and my brain is kind of fried. Monday when I come back I’m going to try to write that c#. Ideally the method should spit out data that doesn’t need formatting. At that point i can drop the url of the method into fullCalendar plugin and it should handle the rest on it's own.

    Thanks again for your help you did clear this up for me.

    dsfx
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2009
    Posts
    151
    Rep Power
    19
    Just to wrap this up i went and grabbed json.Net, i'm serializing my content before i pass it along then just passing it as straight content and not JSON. Full calendar picks it up as JSON and all is right with the world again. Thanks for the help!

    Code:
    // GET JSON Calendar view
            public ActionResult calendarJson()
            {
                var calendarObject = db.reservations;
                int classCount = 0;            
    
                //counts the number of enteries that will be returned
                foreach (var i in calendarObject)
                {
                    classCount++;
                }
    
                //if an entry is going to be returned then...
                if (classCount > 0)
                {
                    //serialize it
                    var calendarJson = JsonConvert.SerializeObject(calendarObject, new IsoDateTimeConverter());
    
                    //remove the line escapes - note: verify to see if nessecary
                    calendarJson = calendarJson.Replace("\\", "");
    
                    //return Json(calendarJson, JsonRequestBehavior.AllowGet);
                    return Content(calendarJson);
                }
                else {
                    return Content("No Data Selected");
                }

IMN logo majestic logo threadwatch logo seochat tools logo