我们希望向正在测试我们应用程序的用户显示一些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
转换为字符串并将其作为替换返回。
是 .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)