`

驳Fish Li 在文章《ASP.NET常被忽视的一些细节》 对.Net JavaScriptSerializer处理DateTime的误解

阅读更多
原帖地址:http://www.cnblogs.com/leonwang/archive/2013/05/29/javascript-datetime.html

Fish Li今天发了一篇火爆的《ASP.NET常被忽视的一些细节》,其中有一个地方我认为他大大的冤枉了微软.Net 类库设计人员,你打开链接就直接跳到了重点,先直接粘贴过来引用如下:


Fish Li

DateTime的JSON序列化


在SP.NET3.5中,微软为ASP.NET为设计了一个JSON序列化的工具类, System.Web.Script.Serialization.JavaScriptSerializer,这个类的使用很广泛,而且比WCF的那个JSON序列化类的兼容性要好。 不过,这个类有一个问题,在序列化DataTime类型时,它生成的结果会让所有人感觉别扭, 其实序列化的结果表现形式还个小问题,在前端写个转换函数就能解决, 然而,如果你需要 用序列化和反序列化的方法来做对象的持久化,就会遇到问题,例如下面的代码:


DateTime dt1 = DateTime.Now;
JavaScriptSerializer jss = new JavaScriptSerializer();

string json = jss.Serialize(dt1);
DateTime dt2 = jss.Deserialize<DateTime>(json);

context.Response.Write(dt1 == dt2);

浏览器显示的结果会让人感到很意外,竟然是:False


出现这个原因与JavaScript的时间格式有关,它使用了UTC时间, 不过,这个理由让人感到难以接受,毕竟其它的反序列化都能还原对象,例如二进制序列化和XML都能正确的还原对象。 没办法,这里只能算是个坑了,所以,如果你要做对象的持久化操作,尽量不要选择JSON序列化。



 以上抱怨其实是没有对javascript时间有正确的理解 , 在mozilla开发者网络看了一篇文章, 介绍js Date对象的 , 详情见:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FDate 


截取其中一段对Date对象的描述原文如下: 


Description


If you supply no arguments, the constructor creates a JavaScript Date object for today's date and time according to local time. If you supply some arguments but not others, the missing arguments are set to 0. If you supply any arguments, you must supply at least the year, month, and day. You can omit the hours, minutes, seconds, and milliseconds.


The JavaScript date is measured in milliseconds since midnight 01 January, 1970 UTC. A day holds 86,400,000 milliseconds. The JavaScript Date object range is -100,000,000 days to 100,000,000 days relative to 01 January, 1970 UTC.


The JavaScript Date object provides uniform behavior across platforms.


The JavaScript Date object supports a number of UTC (universal) methods, as well as local time methods. UTC, also known as Greenwich Mean Time (GMT), refers to the time as set by the World Time Standard. The local time is the time known to the computer where JavaScript is executed.


Invoking JavaScript Date in a non-constructor context (i.e., without the new operator) will return a string representing the current time.


黑体部分是重点中的重点,大意是: javascript 日期以1970年1月1日的世界标准时的到现在的毫秒数计量,一天有86400000毫秒, js日期范围是世界标准时1970年1月1日之前的100000000天到其后的100000000天。


下面我们来看看MSDN上微软对JavaScriptSerializer 对象的说明,参见链接:http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx 


下面是对.net类型和json类型的映射表格的一个截图, 详细见上面链接:



 以上说明了.NET DateTime 转换为JSON格式是以javascript标准日期为基准, 以1970-1-1半夜与当前UTC格式日期相隔的毫秒数为转换结果,这样我们在js中我们可以用Date对象内置函数随意转换为本地格式或其他格式,这样 Fish Li所言的“不过,这个类有一个问题,在序列化DataTime类型时,它生成的结果会让所有人感觉别扭, 其实序列化的结果表现形式还个小问题,在前端写个转换函数就能解决” 就完全不是问题了, 因为根本不需要写什么转换函数,下面是测试代码:



            DateTime now = DateTime.Now;
Console.WriteLine(now.ToString());

JavaScriptSerializer js
= new JavaScriptSerializer();
string json = js.Serialize(now);
Console.WriteLine(json);


 执行结果截图如下:



将JSON字符结果放到javascript中运行如下: 



以上说明其序列化结果表现形式在js环境中完全不是问题, 那在持久化处理中有大问题吗, 还是以Fish Li 的代码来说明: 


DateTime dt1 = DateTime.Now;
JavaScriptSerializer jss = new JavaScriptSerializer();

string json = jss.Serialize(dt1);
DateTime dt2 = jss.Deserialize<DateTime>(json);

context.Response.Write(dt1 == dt2);

浏览器显示的结果会让人感到很意外,竟然是:False   


 其实只要在反序列化时不要忘记转换为本地时,问题就解决了:(因为我们中国在东八区,所以utc时间早了8小时)

 


 

 我回复了 Fish Li, 他回复“你能不能再想远点呢?
你要写的是通用的代码,不仅只处理一个DateTime类型,你不知道哪个类型中有DateTime属性,你打算怎么办?

 

这其实很好解决,如果真要使用本地时间, 应用完全不考虑国际化: 完全可以在含有DateTime成员的类中再加一个String 类型的成员, web界面处理时,只用显示DateTime的String值就可以了, 甚至如完全用一个String类型的DateTime就ok了,再要保存到数据库时再转回DateTime。。 例如:



class Test
{
private DateTime date = DateTime.Now;

/// <summary>
/// Datetime format Date
/// </summary>
public DateTime Date
{
get
{
return date;
}
set
{
date
= value;
}
}

/// <summary>
/// String format Date
/// </summary>
public String DateString
{
get
{
return date.ToString();
}
}
}


其实主流的JSON转换函数都是如MS库相同处理,所以我没法想到一个比标准还标准的所谓通用解决方案了  哎, 今天又没多少时间写win8 博客园客户端了 。。 


本文链接

分享到:
评论

相关推荐

    JavaScriptSerializer序列化DateTime

    在asp.net中使用JavaScriptSerializer实现Datetime的JSON序列化时会出现格式转换问题,造成Web前端解析出问题,解决的方式在网上也看了一些,但感觉太繁琐,JSON.NET之前也用过,感觉太过重量级,不是很喜欢了,因为...

    asp.net json格式数据

    在ASP.NET中,处理JSON主要涉及以下几个关键知识点: 1. **JSON序列化与反序列化**: - **序列化**:将.NET对象转换为JSON字符串,以便通过HTTP发送到客户端。ASP.NET提供了`System.Web.Script.Serialization`命名...

    ASP.NET与Echarts实现前后端数据的交互

    在"ASP.NET与Echarts实现前后端数据的交互"这个主题中,核心是利用ASP.NET后端处理数据,并通过Echarts前端展示。具体步骤如下: 1. **后端数据处理**:在ASP.NET中,你可以使用ADO.NET或Entity Framework等库来...

    【ASP.NET编程知识】JSON在ASP.NET中使用方法.docx

    在ASP.NET中,JSON常用于Web应用程序的客户端和服务器之间的数据交互,因为它的结构与JavaScript对象非常相似,使得在AJAX(Asynchronous JavaScript and XML)应用中尤为适用。 Json.NET是.NET框架中广泛使用的...

    asp.net天气预报

    这个实例主要展示了如何利用网络API(如中国天气预报网的接口)获取数据,并在ASP.NET环境中进行处理和展示。通过学习这个例子,开发者可以掌握以下几个关键知识点: 1. **ASP.NET Web Forms或MVC框架**:本示例...

    asp.net用jquery 一般处理程序做的

    在ASP.NET中,我们通常使用JavaScriptSerializer类或Newtonsoft.Json库(如Json.NET)将C#对象转换为JSON字符串,以便于AJAX请求接收。在描述中提到的“table用json”很可能是指服务器端的ASP.NET应用生成了JSON格式...

    asp.net公共类

    ASP.NET公共类是开发者在构建基于ASP.NET平台的Web应用程序时经常会用到的一类工具性代码,它们提供了许多通用的功能,以简化开发流程并提高代码的可重用性。这些类通常封装了一些常见的操作,如数据处理、验证、...

    asp.net的ajax传值

    6. **JSON序列化和反序列化**:在ASP.NET中,JavaScriptSerializer或DataContractJsonSerializer类可以用来将对象序列化为JSON字符串,以便通过AJAX传递。相反,反序列化则将JSON数据转换回C#对象。 7. **AJAX回调...

    ajax asp.net通用查询

    3. 后台处理:在ASP.NET的代码-behind文件中,定义一个处理查询请求的Web方法。这个方法接收前端传递的查询参数,执行SQL查询(可能涉及多表联查和条件组合),并返回查询结果。 4. 数据格式化:查询结果可能需要...

    ASP.NET jqGRID 控件 源代码 示例

    在ASP.NET MVC中,可以使用ActionResult返回JSON数据,创建一个Controller方法来处理jqGrid的请求: ```csharp public ActionResult GetGridData() { var data = _yourService.GetData(); return Json(data, ...

    简单AJAX与ASP.NET聊天室

    在ASP.NET中,可以使用`JavaScriptSerializer`类或`Json.NET`库将数据序列化为JSON格式。 4. **实时性**:为了让聊天室具有实时性,通常需要一种机制来实现实时推送。传统的HTTP长轮询、短轮询方式会消耗大量资源。...

    asp.net生成json对象,jquery读取

    总结一下,ASP.NET生成JSON对象主要通过`JavaScriptSerializer`,而jQuery则提供了`$.getJSON()`和`$.ajax()`等方法方便地在客户端读取和处理这些数据。这种方法使得前后端之间的数据交互变得更加简单高效,尤其在...

    JQuery zTree asp.net实例

    **jQuery zTree ASP.NET 实例详解** 在Web开发中,我们常常需要展示层次结构的数据,例如组织架构、文件目录等,这时Tree控件就显得尤为重要。`jQuery zTree`是一款非常流行的JavaScript Tree插件,它提供了丰富的...

    asp.net js实现统计图

    在ASP.NET中,我们可以使用`JavaScriptSerializer`类将C#对象转换为JSON字符串,然后通过AJAX请求发送到客户端。在JavaScript端,可以使用`JSON.parse()`函数将JSON字符串解析成JavaScript对象。 2. **AJAX...

    asp.net三级联动

    在ASP.NET开发中,"三级联动"是一种常见的交互设计,常用于地区选择、类别筛选等场景,用户在一级菜单选择后,二级菜单自动更新,二级菜单选择后,三级菜单再随之变化。这种功能的实现主要涉及到客户端JavaScript和...

    asp.net flash图表控件

    ASP.NET Flash图表控件是一种用于在Web应用中创建动态、交互式图表的工具,它结合了ASP.NET的强大功能和Flash的视觉吸引力。OpenFlashChart是一个流行的开源库,用于生成高质量的图表,它提供了丰富的定制选项,使...

    Jquery Asp.net AJAX 异步通讯

    本篇文章将详细探讨如何使用jQuery与ASP.NET的几种后端技术进行异步通信。 ### 1. 异步调用ASP.NET的aspx.cs方法 在ASP.NET中,aspx.cs文件是页面的后台代码逻辑层,包含C#或VB.NET代码。通过jQuery的$.ajax()函数...

    asp.net(c#) 与 highcharts 数据库交互

    ASP.NET (C#) 与 Highcharts 数据库交互是一个关键的技能点,它涉及Web开发中的数据可视化和后端数据处理。Highcharts 是一个流行的JavaScript图表库,用于在网页上创建交互式的图表,而ASP.NET (C#) 则是微软的...

    asp.net json使用

    在ASP.NET中,可以使用`System.Web.Script.Serialization`命名空间下的`JavaScriptSerializer`类来实现JSON序列化。例如,将一个C#对象转换为JSON字符串: ```csharp using System.Web.Script.Serialization; ...

    UCenter 与 Asp.net 通讯

    3. **JSON序列化与反序列化**:UCenter的API通常返回JSON格式的数据,因此你需要使用.NET的`System.Web.Script.Serialization.JavaScriptSerializer`类或者第三方库如Newtonsoft.Json来处理JSON数据的序列化与反序列...

Global site tag (gtag.js) - Google Analytics