2012-04-18 51 views
8

我們想向正在測試我們的應用程序的用戶顯示一些JSON。所以我們在ASP.NET代碼後面的文件中調用我們的REST服務,並返回一個字符串,它包含很多JSON。將字符串中的JSON日期替換爲更具可讀性的日期

然後,我們把它放在頁面中的PRE元素中,調用美化來創建可讀的JSON,並且都很好:顯示了一些可讀的內容。

不錯,但一兩件事:所有日期都在正常的JSON格式這樣顯示「/日期(1319266795390 + 0800)/」

我想要做的是「正常」取代那些JSON日期日期,在JSON(C#)字符串中,所以在後面的代碼中,在將字符串添加到PRE元素之前。

我曾想過一些正則表達式,但我無法找出解決方案如何...

+1

你可以在你的問題的文本中包含更多的JSON字符串的完整例子,你想讓它更「可讀」。問題在於JSON主要用於將對象轉換爲字符串,以便能夠傳輸到Web客戶端並將JSON轉換回JavaScript對象。 JavaScript對象應該不可讀。如果你有例如數組中的日期爲一個屬性的對象,那麼你不能使它對人類可讀性好。因此,瞭解您將哪種數據(哪個對象)序列化爲JSON字符串非常重要。 – Oleg 2012-05-07 13:53:32

+0

你會考慮一個JavaScript解決方案嗎,還是你使用C#來完成轉換? – jmort253 2012-05-10 02:36:01

回答

5

是問題出在字符串中。 JavaScript Date對象將解析該格式並生成可讀版本,因此Date(1319266795390+0800)返回「Wed Apr 18 2012 08:13:22 GMT-0500(Central Daylight Time)」。

要從字符串中刪除正斜槓,您可以使用正則表達式的替換函數:"/Date(1319266795390+0800)/".replace(/\//g, '')

+0

啊,但我的字符串包含的不僅僅是那個日期,它還包含50個其他人的屬性,其中包含幾個日期。 – Michel 2012-04-18 14:17:07

+0

Michel - 正則表達式本質上是用來從很長的字符串中檢索特定的數據。 Eric所建議的應該可以完全用JavaScript來完成。 – jmort253 2012-05-10 02:24:13

1

用作正則表達式是這樣的:

(?<= /Date\() 
    (?<ticks>[0-9]+) 
    ((?<zonesign>[+-]) 
    (?<zonehour>[0-9]{2}) 
    (?<zoneminutes>[0-9]{2}) 
)? 
(?= \)/) 

這將匹配的/Date(1319266795390+0800)/括號內的部分。然後,您可以撥打Regex.Replace對整個JSON字符串來代替數字格式良好的DateTime

使用Match對象,你在比賽中評估委託取得並提取蜱,zonesign,zonehour和zoneminutes部分,將其轉換爲整數。

然後將javascript ticks轉換爲.NET ticks(應該是* 10000),使用ticks構造.NET DateTime並添加/減去時區的小時和分鐘。 將DateTime轉換爲字符串並將其作爲替換返回。

1

如果您的JSON是.NET類的序列化表示,也許您可​​以使用DataContractJsonSerializer在服務器上對其進行反序列化,或者您可能只需爲JSON對象定義存根類(如果不需要)通用的解決方案來處理多個數據集:

string json = "{\"Test\": \"This is the content\"}"; 
DataContractJsonSerializer ds = new DataContractJsonSerializer(typeof(TestJson)); 
var deserialisedContent = ds.ReadObject(new MemoryStream(Encoding.ASCII.GetBytes(json))); 

foreach (var field in typeof (TestJson).GetFields()) 
{ 
    Console.WriteLine("{0}:{1}", field.Name, field.GetValue(deserialisedContent)); 
} 

... 

[DataContract] 
private class TestJson 
{ 
    [DataMember] 
    public string Test; 
} 
13

心中已經被處理的JSON字符串日期一段時間以來,there's no standard way對於和這就是爲什麼有這麼多不同的方式來做到這一點!如果JSON規範能夠首先爲日期指定標準格式,那麼可能會更好!

微軟正在做它以自己的方式,在UTC格式的自1970年以來計數毫秒這是一樣的東西"/Date(1319266795390+0800)/"

我們已經改變上述字符串ISO-8601 format自從使用上ASP.Net JavaScriptSerializer輸出的頂端正則表達式。這是一個W3C標準,人類可讀和大多數瀏覽器連載日期字符串的方式,方法如下:

static readonly long DATE1970_TICKS = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).Ticks; 
static readonly Regex DATE_SERIALIZATION_REGEX = new Regex(@"\\/Date\((?<ticks>-?\d+)\)\\/", RegexOptions.Compiled); 

static string ISO8601Serialization(string input) 
{ 
    return DATE_SERIALIZATION_REGEX.Replace(input, match => 
    { 
     var ticks = long.Parse(match.Groups["ticks"].Value) * 10000; 
     return new DateTime(ticks + DATE1970_TICKS).ToLocalTime().ToString("yyyy-MM-ddTHH:mm:ss.fff"); 
    }); 
} 

您可以輕鬆更改格式,以滿足您的需求,看到自定義日期和時間格式check out MSDN article here

這裏是如何使用它:

JavaScriptSerializer ser = new JavaScriptSerializer(); 
var JsonSrt = ISO8601Serialization(ser.Serialize(DateTime.Now)); // "\"2012-05-09T14:51:38.333\"" 

更新:

有一個阿爾特rnative來調整JSON字符串從服務器返回JavaScript中更可讀的形式使用正則表達式:

var str = "/Date(1319266795390+0800)/"; 
str.replace(/\/Date\((\d+)\+\d+\)\//, function (str, date) { 
    return new Date(Number(date)).toString(); 
}); 
+0

很好的解決方案。我們正在使用自動將對象轉換爲JSON的WCF框架。在代碼中,我們只返回一個用數據庫屬性註釋的POCO對象,並且當調用該函數時,由於我認爲項目類型的性質,輸出被轉換爲JSON。我想說的是(據我所知)在代碼中沒有時間/地方,我可以用自定義數據替換代碼踢出 – Michel 2012-05-14 09:51:14

+0

WCF使用'DataContractJsonSerializer'來序列化POCO/DataContract對象,您可以調整默認的JSON序列化器,並用自定義的替換'DataContractJsonSerializer'!以下是一篇文章,向您展示如何:http://blogs.msdn.com/b/carlosfigueira/archive/2011/05/03/wcf-extensibility-message-formatters.aspx 無論如何,還有一種方法可以調整JSON文本從服務器返回使用JavaScript中的正則表達式,因爲我將在 – 2012-05-14 15:46:12

+0

以上的更新中顯示這適用於日期(##),但不是日期(## + ####),即不包含任何時區信息。嘗試對此字符串執行此操作:「{\」EndTime \「:\」\\/Date(1381479678557)\\/\「,\」StartTime \「:\」\\/Date(1381479678557 + 0200)\\/\ 「}」。它只取代EndTime而不是StartTime – JensB 2013-10-11 08:23:36

3

您可以使用此:

string date = "/Date(1319266795390+0800)/"; 
string regex = @"/Date\((.*?)\+(.*?)\)/"; 
Match match = Regex.Match(date, regex); 
DateTime d = new DateTime(1970, 01, 01).AddMilliseconds(long.Parse(match.Result("$1"))); 
2

假設你希望類序列如下所示:

public class Something 
{ 
    public int ID; 
    public string Name; 
    public DateTime Date; 
} 

將其更改爲:

public class Something 
    { 
     public int ID; 
     public string Name; 
     public DateTime Date; 
     public string HumanReadableDate { get { return Date.ToLongDateString(); } } 
    } 

,或者,如果你想額外的屬性只有在顯示測試環境:

public class Something 
    { 
     public int ID; 
     public string Name; 
     public DateTime Date; 
     #if DEBUG 
     public string HumanReadableDate { get { return Date.ToLongDateString(); } } 
     #endif 
    } 

也,而不是.ToLongDateString()可以使用.ToString("yyyy-MM-dd HH:mm")或任何其他形式

1

製作例如出生日期我在這裏定義字符串屬性,並返回你的日期時間變量:

public string DateOfBirthString 
    { 
     get { return DateOfBirth.ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss"); } 
     set { DateOfBirth = string.IsNullOrEmpty(value) ? new DateTime(1900, 1, 1) : Convert.ToDateTime(value); } 
    } 

,因爲這將返回字符串,所以它將在客戶端是一樣的,所以並且從用戶處取得字符串dateTime並將其轉換。

0
string input = [yourjsonstring]; 
MatchEvaluator me = new MatchEvaluator(MTListServicePage.MatchDate); 
string json = Regex.Replace(input, "\\\\/\\Date[(](-?\\d+)[)]\\\\/", me, RegexOptions.None) 
相關問題