2016-12-21 42 views
1

我注意到,當使用Newtonsoft.Json.Linq命名空間解析JSON時,選擇日期值將返回與原始JSON格式不同的字符串。這是什麼造成的?用C#中的Newtonsoft.Json.Linq查詢JSON操作日期字符串

例如:

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是使用Microsoft.AspNetCore.WebUtilities.HttpRequestStreamReader()獲得的原始JSON的字符串表示。

我希望(string)entry["commit"]["committer"]["date"]返回相同的字符串是在JSON,在這種情況下,格式爲"yyyy-MM-ddTHH:mm:ssz"但上面的代碼表明它是不是在格式"MM/dd/yyyy HH:mm:ss"。爲什麼格式發生了變化以及時區和時區標識符發生了什麼變化?

我唯一能想到的就是致電JArray.Parse(string)來識別和操縱日期。是這樣嗎?如果是這樣,那肯定是不受歡迎的行爲?如果不是,發生了什麼事?

編輯 這可以用在淨Core控制檯應用下面的例子來製備,加入"Microsoft.AspNetCore.Mvc": "1.1.0"project.json文件:

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(); 
     } 
    } 
} 

隨着19/12/2016 11:53:13的輸出,這是有趣的,因爲它是又一種格式(dd/MM/yyyy HH:mm:ss)。這可能與本地化設置有關嗎?如果是這樣,爲什麼?這也令人困惑,因爲IIS Express與我執行上述代碼的機器運行在同一臺機器上,但我認爲這需要主機機器本地化。這也意味着,如果我部署到與本地開發機器不同的本地化服務器上​​,原始文章中的格式說明符將會因爲異常而最終得到等於new DateTime(0)的值。這是什麼我不理解?

回答

2

您是對的,JArray.Parse的電話會自動爲您解析日期(by design)。

我想獲得的原始字符串,你需要直接使用讀者:

var s = @"[{ 
      ""commit"": { 
       ""committer"": { 
        ""name"": ""GitHub"", 
        ""email"": ""[email protected]"", 
        ""date"": ""2016-12-19T11:53:13Z"" 
       } 
      } 
     } 
    ]"; 

    using (var sr = new StringReader(s)) 
    using (var jr = new JsonTextReader(sr) { DateParseHandling = DateParseHandling.None }) 
    { 
     var arr = JArray.ReadFrom(jr); 

     foreach (var entry in arr) 
     { 
      Console.WriteLine(entry["commit"]["committer"]["date"].ToString()); // 2016-12-19T11:53:13Z 
     } 
    } 
+0

謝謝,無論是對於這個問題的例子和GitHub對話的鏈接。看起來像是一種不受歡迎的效果,但如果圖書館的作者喜歡這個功能,那麼我想會是什麼樣的! –

+0

事實證明,我想要實現的最簡單的解決方案是將結果強制轉換爲DateTime:DateTime date =(DateTime)entry [「commit」] [「committer」] [「date」]; 。不知道爲什麼以前沒有發生過,儘管知道DateParseHandling選項對於我是否明確需要原始字符串非常有用。 –

0

Json.Net存儲日期的前瞻性值日期在內部,而不是字符串(它對於其他基地一樣數據類型也是如此)。所以當你開始操作這些值時,實際上是處理該值的內部表示形式,這是一個日期類型,然後當你以字符串的形式將其取出時,就會返回該內部值的字符串轉換,而不是你所期望的原始字符串。

這是處理JS中的JSON與使用C#中的Json.Net之間的顯着區別 - 一個不幸的人之一,恕我直言,因爲它需要額外的代碼來解決。

+0

基本上Json.Net就像你這樣做:'''date「:new Date(」....「)''' –