0

Q: How do I make Json.NET successfully convert this json date structure to C# DateTime?

Hello, I am trying to deserialize a return value from a method call on an existing Meteor.js app using the DDP protocol into a known/strict return structure.

I am using dynamics to implement most basic things, but, moving on to strict structures to get benefit from type safety and intelisense on C#s side.

However it is failing to successfully deserialize the Javascripts Date() into C#s DateTime using the ddp serialization structure for the javascripts Date():

"when": {
        "$date": 1406886657338
 }

Q: How do I make Json.NET successfully convert this json date structure to C# DateTime?

If a "protocol" middleware was possible, having DateTime to DDPs Date() would be awsome too.

My structures:

namespace xxxx.API.Structures
{
    public struct loginParams
    {
        public string email;
        public string apiClient;
    }

    public struct loginReturn
    {
        public string result;
        public string session;
        public string email;
        public string user;
        public DateTime when;
        public string client;
    }
}

The return value I want converted into loginReturn :

xxxx.DDP.Client.DDPClient.ConnectGS.AnonymousMethod__1 (err=(null), res={{
  "result": "sucess",
  "session": "v3gozkHgceoqGqsfd",
  "email": "xxxx@gmail.com",
  "user": "hueun3s8rKQWsoQDT",
  "server": "Lnf3vAFaeoCiMWriY",
  "when": {
    "$date": 1406886657338
  },
  "client": "OfficialxxxxPlugin"
}}) in /Volumes/2TB/Files/Documents/Dropbox/Development/C#/xxxx/xxxx/xxxxAPI/xxxx.DDP.Client/DDPClient.cs:43
Joao Carlos
  • 749
  • 1
  • 11
  • 32

2 Answers2

0

The value in the JSON response is a Unix timestamp. It gives the the number of milliseconds since 1 January 1970 00:00:00 UTC.

So you can do:

String JSONDate = "1406886657338";
DateTime when = new DateTime(1970, 1, 1, 0, 0, 0).AddMilliseconds(Convert.ToDouble(JSONDate));
Tobias
  • 4,034
  • 1
  • 28
  • 35
  • I am sorry I must have not explained myself correctly. I want to have Json.NET convert the values for me, using some type of conversion overload or protocol change to have it convert all of those $date (since $ means its a "special" field, that needs to be used in a different matter), when serializing and deserializing entire objects/strings. The code you provided is correct, yes, but, its not the "meat" of the solution. I want to add an "exception" for those fields whose keys start with "$date". – Joao Carlos Aug 01 '14 at 21:30
0

This isnt the best possible solution, and doesnt really add anything to the topic I wanted to discuss, but, for this specific problem, here is a fix that works.

private static Regex _dollarDateRegex = new Regex ("\"\\$date\\\":\\s?(\\d+)");
if (message.Contains ("$date")) {
                var matches = _dollarDateRegex.Matches (message);
                foreach (Match match in matches) {
                    string date = match.Groups [1].Value;
                    int startOfDate = message.IndexOf ("$date\":" + date, StringComparison.CurrentCulture);
                    int startOfObject = startOfDate;
                    int endOfObject = startOfDate;
                    // skip to first { behind
                    while (message [startOfObject--] != '{') {
                    }
                    // skip to last } in front
                    while (message [endOfObject++] != '}') {
                    }                       
                    var diff = endOfObject - startOfObject;
                    StringBuilder s = new StringBuilder (message);
                    s.Remove (startOfObject, diff);
                    s.Insert (startOfObject, ": new Date(" + date + ")");
                    message = s.ToString ();
                }
            }

This yields :

{
   ...
   when: new Date(2191283823),
   ...
}
Joao Carlos
  • 749
  • 1
  • 11
  • 32