将字符串中的 JSON 日期替换为更具可读性的日期



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

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

很好,但有一点:所有日期都以正常的 JSON 格式显示,例如"/Date(1319266795390+0800)/"

我想做的是在 JSON (C#) 字符串中将这些 JSON 日期替换为"正常"日期,因此在后面的代码中,在我将字符串添加到 PRE 元素之前。

我在想一些正则表达式,但我不知道如何......

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

Microsoft以自己的方式做到这一点,以 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""

更新:

还有一种替代方法可以使用正则表达式将从 JavaScript 服务器返回的 JSON 字符串调整为更具可读性的形式:

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

解决方案在问题中显示的字符串中。 JavaScript Date 对象将解析该格式并生成可读版本,因此Date(1319266795390+0800)返回"星期三 Apr 18 2012 08:13:22 GMT-0500(中部夏令时间)"。

要从字符串中删除正斜杠,您可以将 replace 函数与正则表达式一起使用:"/Date(1319266795390+0800)/".replace(///g, '') .

你可以使用这个:

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

假设要序列化的类如下所示:

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
    }

此外,您可以使用.ToString("yyyy-MM-dd HH:mm")或任何其他格式代替.ToLongDateString()

用作正则表达式,如下所示:

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

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

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

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

如果您的 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;
}

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

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

为我在这里定义的出生日期创建一个字符串属性,并将您的日期时间变量返回为:

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

因为这将返回字符串,因此它在客户端是相同的,因此并且 aslo 从用户那里获取字符串 dateTime 并对其进行转换。

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

最新更新