I've noticed that when parsing JSON using the Newtonsoft.Json.Linq namespace, selecting a date value returns a string in a different format to that of the original JSON. What is causing this?
For example:
JSON
[
{
...
"commit": {
...
"committer": {
"name": "GitHub",
"email": "[email protected]",
"date": "2016-12-19T11:53:13Z"
},
...
}
...
}
...
]
C#
...
List<Commit> commits = new List<Commit>();
JArray commitsArray = JArray.Parse(rawCommits);
...
foreach (var entry in commitsArray)
{
DateTime date;
CultureInfo provider = CultureInfo.InvariantCulture;
string format = "MM/dd/yyyy HH:mm:ss";
try
{
date = DateTime.ParseExact((string)entry["commit"]["committer"]["date"], format, provider);
}
catch (FormatException ex)
{
date = new DateTime(0);
}
...
}
...
rawCommits is a string representation of the raw JSON obtained using Microsoft.AspNetCore.WebUtilities.HttpRequestStreamReader().
I would expect (string)entry["commit"]["committer"]["date"] to return the same string as is in the JSON, in this instance in the format "yyyy-MM-ddTHH:mm:ssz" but as the above snippet shows it is instead in the format "MM/dd/yyyy HH:mm:ss". Why has the format changed and what has happened to the time and timezone identifiers?
The only thing I can think is that the call to JArray.Parse(string) identifies and manipulates the date. Is this the case? If so, surely it is undesirable behaviour? If not, what is going on?
Edit
This can be produced with the following example in an .Net Core Console App, adding "Microsoft.AspNetCore.Mvc": "1.1.0" to the project.json file:
using Newtonsoft.Json.Linq;
using System;
namespace JsonExample
{
public class Program
{
public static void Main(string[] args)
{
string json = "{\"date\": \"2016-12-19T11:53:13Z\"}";
JToken jToken = JToken.Parse(json);
Console.WriteLine(jToken["date"]);
Console.ReadLine();
}
}
}
With an output of 19/12/2016 11:53:13, which is interesting because it is yet another format (dd/MM/yyyy HH:mm:ss). Does this perhaps have anything to do with localisation settings? If so, why? It's also confusing, given that IIS Express is running on the same machine as that on which I executed the above code, yet I thought it took the host machines localisation. It also means if I deploy to a server with different localisation than my development machine the format specifier in the original post will because an exception and I'll end up with a value equal to new DateTime(0). What is it I am not understanding?