Odd JSON Date Formats

For some reason, they decided to use the ASP.NET AJAX / WCF Web Services date format (“/Date(1399100400000-0700)/”) for the Bing Webmaster API JSON response instead of the more conventional ISO 8601 format (“2014-05-02T11:23:31.324Z”) used in the XML response.

If you’ve never seen one of these, I feel for you. The big number is the number of milliseconds since Unix EPOCH (Jan. 1, 1970), followed by a timezone offset. Of course, the timezone offset is in hours / minutes, so -0700 means -7 hrs from UTC/GMT, and you’ll have to either find a utility to do the conversion for your chosen language, or parse the hours and minutes, and use those to offset the milliseconds delta.

Oh, and just to keep things interesting, in some responses, there is no timezone portion. I think this is supposed to mean ‘just use the date, not the time’, but if your utility automatically converts to local timezone, having a zero offset could cause you to get the wrong date.

You also have to take into account the random ‘no date’ occurances, which can happen.

Here’s the algorithm I have settled on (written in C#):

DateTime d2 = DateTime.Today;
if (str.StartsWith("/Date(-"))
{
// null
}
else if (str.StartsWith("/Date(") && str.EndsWith(")/"))
{
bool neg = true;
int hyph = str.LastIndexOf('-');
if (hyph < 0)
{
neg = false;
hyph = str.LastIndexOf('+');
}
if (hyph > 0)
{
Double num = 0;
bool okNum = Double.TryParse(str.AsSpan(6, hyph - 6), out num);
Double hours = 0;

bool okHours = Double.TryParse(str.AsSpan(hyph + 1, 2), out hours);
Double mins = 0;

bool okMins = Double.TryParse(str.AsSpan(hyph + 3, 2), out mins);
if (neg)
num = num - (hours * 60 * 60 * 1000) - (mins * 60 * 1000);
else
num = num + (hours * 60 * 60 * 1000) + (mins * 60 * 1000);
d2 = new DateTime(1970, 1, 1).AddMilliseconds(num);
array[i] = d2;
}
else
{
Double num = 0;
string n = str.Substring(6, str.Length - 8);
bool okNum = Double.TryParse(str.AsSpan(6, str.Length - 8), out num);
d2 = new DateTime(1970, 1, 1).AddMilliseconds(num).Date; // no time component
array[i] = d2;
}
}