9

我们想向正在测试我们的应用程序的用户展示一些 JSON。所以我们在 ASP.NET 代码隐藏文件中调用我们的 REST 服务并返回一个字符串,其中包含大量 JSON。

然后我们将它放在页面中的 PRE 元素中,调用 beautify 来创建可读性好的 JSON,一切都很好:显示了人类可读的内容。

好的,但有一件事:所有日期都以正常的 JSON 格式显示,如“/Date(1319266795390+0800)/”

我想要做的是在 JSON (C#) 字符串中用“正常”日期替换那些 JSON 日期,所以在后面的代码中,在我将字符串添加到 PRE 元素之前。

我正在考虑一些正则表达式,但我无法弄清楚如何......

4

9 回答 9

14

一段时间以来,我一直在处理 JSON 字符串中的日期,没有标准的方法,这就是为什么有这么多不同的方法来做到这一点!如果 JSON 规范首先可以指定日期的标准格式,也许会更好!

微软正在以自己的方式做这件事,以 UTC 格式计算自 1970 年以来的毫秒数,这类似于"/Date(1319266795390+0800)/"

自从在输出之上使用正则表达式以来,我们一直将上述字符串更改为ISO-8601 格式ASP.Net JavaScriptSerializer。它是 W3C 标准,人类可读,也是大多数浏览器将 Date 序列化为字符串的方式,方法如下:

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

您可以轻松更改格式以满足您的需求,查看自定义日期和时间格式,请查看此处的 MSDN 文章

以下是它的使用方法:

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

更新:

有一种替代方法可以使用 Regex 将 JavaScript 中从服务器返回的 JSON 字符串调整为更易读的形式:

var str = "/Date(1319266795390+0800)/";
str.replace(/\/Date\((\d+)\+\d+\)\//, function (str, date) {
    return new Date(Number(date)).toString();
});
于 2012-05-09T14:19:46.017 回答
5

解决方案在问题中显示的字符串内。JavaScript Date 对象将解析该格式并生成可读版本,因此Date(1319266795390+0800)返回“Wed Apr 18 2012 08:13:22 GMT-0500 (Central Daylight Time)”。

要从字符串中删除正斜杠,您可以使用带有正则表达式的替换函数:"/Date(1319266795390+0800)/".replace(/\//g, '').

于 2012-04-18T13:21:48.513 回答
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")));
于 2012-05-10T10:07:54.313 回答
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")或任何其他格式代替

于 2012-05-10T21:37:45.563 回答
1

用作正则表达式,例如:

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

这将匹配括号内的部分/Date(1319266795390+0800)/。然后,您可以调用Regex.Replace整个 JSON 字符串来用格式正确的数字替换数字DateTime

使用Match您在匹配评估器委托中获得的对象并提取刻度、区域符号、区域小时和区域分钟部分,将其转换为整数。

然后将 javascript 记号转换为 .NET 记号(应为 *10000),用DateTime记号构造 .NET 并添加/减去时区的小时和分钟。将 转换DateTime为字符串并将其作为替换返回。

于 2012-05-07T22:00:36.067 回答
1

如果您的 JSON 是 .NET 类的序列化表示,也许您可​​以使用DataContractJsonSerializer在服务器上对其进行反序列化,或者如果您不需要通用解决方案来处理多个数据集:

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;
}
于 2012-05-09T05:26:13.977 回答
1

使用 Newtonsoft.JSON。您可以为每种类型提供自己的序列化程序,并根据需要序列化日期。

http://james.newtonking.com/projects/json-net.aspx

于 2012-05-10T19:02:26.797 回答
1

创建一个字符串属性,例如我在此处定义的 dateofbirth,并将您的 datetime 变量返回为:

    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 并转换它。

于 2012-05-11T13:13:40.857 回答
0
string input = [yourjsonstring]; 
MatchEvaluator me = new MatchEvaluator(MTListServicePage.MatchDate);
string json = Regex.Replace(input, "\\\\/\\Date[(](-?\\d+)[)]\\\\/", me, RegexOptions.None)
于 2014-02-18T15:08:38.590 回答