Jus*_*tin 13 .net datetime utc javascriptserializer
我们的客户希望在浏览器中显示日期和时间值,就像它们在数据库中一样,我们将它们作为UTC存储在数据库中.
起初我们在序列化和Javascript方面遇到了一些问题.DateTime值被移动了两次 - 首先匹配机器的本地时区,然后匹配浏览器中的时区.我们通过向JavaScriptSerializer添加自定义转换器来修复它.我们在Serialize覆盖中将DateTime标记为DateTimeKind.Utc.从Serialize中提取数据有点困难,但是我们发现了一些Uri hack,这有助于在相同的JavaScriptSerializer/Date(286769410010)/格式中返回DateTime值,但没有转移到本地时间.在Javascript方面,我们修补了KendoUI JS库来偏移构造的Date()对象,使它们看起来好像是UTC.
然后我们开始在另一方面工作,反序列化.同样,我们必须调整我们的代码以使用自定义stringify而不是JSON.stringify,这会在从本地时间转换为UTC时再次抵消数据.到目前为止,一切似乎都很好.
但看看这个测试:
public void DeserialiseDatesTest()
{
var dateExpected = new DateTime(1979, 2, 2,
2, 10, 10, 10, DateTimeKind.Utc);
// this how the Dates look like after serializing
// anothe issue, unrelated to the core problem, is that the "\" might get stripped out when dates come back from the browser
// so I have to add missing "\" or else Deserialize will break
string s = "\"\\/Date(286769410010)\\/\"";
// this get deserialized to UTC date by default
JavaScriptSerializer js = new JavaScriptSerializer();
var dateActual = js.Deserialize<DateTime>(s);
Assert.AreEqual(dateExpected, dateActual);
Assert.AreEqual(DateTimeKind.Utc, dateActual.Kind);
// but some Javascript components (like KendoUI) sometimes use JSON.stringify
// for Javascript Date() object, thus producing the following:
s = "\"1979-02-02T02:10:10Z\"";
dateActual = js.Deserialize<DateTime>(s);
// If your local computer time is not UTC, this will FAIL!
Assert.AreEqual(dateExpected, dateActual);
// and the following fails always
Assert.AreEqual(DateTimeKind.Utc, dateActual.Kind);
}
Run Code Online (Sandbox Code Playgroud)
为什么JavaScriptSerializer将\/Date(286769410010)\/字符串反序列化为UTC时间但是1979-02-02T02:10:10Z当地时间?
我们尝试在自定义中添加Deserialize方法,JavascriptConverter但问题是如果我们的JavascriptConverter具有以下类型,则永远不会调用Deserialize:
public override IEnumerable<Type> SupportedTypes
{
get { return new List<Type>() { typeof(DateTime), typeof(DateTime?) }; }
}
Run Code Online (Sandbox Code Playgroud)
我想,只有在SupportedTypes包含具有DateTime字段的复杂实体的类型时才会调用Deserialize .
所以,JavaScriptSerializer和JavascriptConverter有两个矛盾:
有没有简单的方法来解决这些问题?我们有点害怕替换JavaScriptSerializer其他一些序列化程序,因为我们正在使用的某些第三方库可能依赖于某些"功能/错误" JavaScriptSerializer.
Mat*_*int 41
JavaScriptSerializer,并DataContractJsonSerializer充满了虫子.请改用json.net.甚至微软也在ASP.Net MVC4和其他近期项目中进行了这一切换.
该/Date(286769410010)/格式是专有的,由Microsoft制作.它有问题,并没有得到广泛的支持.你应该1979-02-02T02:10:10Z到处使用这种格式.这在ISO8601和RF3339中定义.它既具有机器可读性,又具有词汇可读性,文化不变性,且无歧义.
在JavaScript中,如果您可以保证您将在较新的浏览器上运行,那么请使用:
date.toISOString()
Run Code Online (Sandbox Code Playgroud)
参考这里.
如果您想要完整的跨浏览器和旧浏览器支持,请改用moment.js.
UPDATE
JavaScriptSerializer顺便说一句,如果你真的想继续使用,你可以反序列化为a DateTimeOffset,这将保留正确的时间.然后,您可以DateTime从那里获取UTC ,如下所示:
// note, you were missing the milliseconds in your example, I added them here.
s = "\"1979-02-02T02:10:10.010Z\"";
dateActual = js.Deserialize<DateTimeOffset>(s).UtcDateTime;
Run Code Online (Sandbox Code Playgroud)
您的测试现在将通过.
| 归档时间: |
|
| 查看次数: |
22653 次 |
| 最近记录: |