JavaScriptSerializer类序列化日期时需要注意的问题

1、让我们来看看使用JavaScriptSerializer类序列化日期会出现什么问题?

1)创建用于序列化的测试类,如下:

 1 public class Person
 2 {
 3     public int ID { get; set; }
 4     public string Name { get; set; }
 5     public DateTime Birthday { get; set; }
 6 
 7     // 重写ToString方法是为了方便查看结果
 8     public override string ToString()
 9     {
10         return string.Format("ID:{0};Name:{1};Birthday:{2}", this.ID, this.Name, this.Birthday);
11     }
12 }
View Code

2)需要引用System.Web.Extensions程序集,因为JavaScriptSerializer类定义于该程序集。编写如下代码进行测试:

 1 Person p = new Person();
 2 p.ID = 1;
 3 p.Name = "zhangsan";
 4 p.Birthday = new DateTime(1999, 11, 11, 11, 11, 11);
 5 Console.WriteLine("序列化前的对象:"+p.ToString());
 6 
 7 JavaScriptSerializer jss = new JavaScriptSerializer();
 8 string json = jss.Serialize(p);
 9 Console.WriteLine("序列化后的JSON字符串:" + json);
10 
11 Person p2 = jss.Deserialize<Person>(json);
12 Console.WriteLine("反序列化的对象:"+p2.ToString());
13 
14 Console.ReadLine();
View Code

运行结果如下:

序列化前的对象:ID:1;Name:zhangsan;Birthday:1999/11/11 11:11:11 
序列化后的JSON字符串:{"ID":1,"Name":"zhangsan","Birthday":"\/Date(942289871000)\/"}
反序列化的对象:ID:1;Name:zhangsan;Birthday:1999/11/11 3:11:11

从结果中可以看出如下几点问题:

a、序列化前的日期和序列化后的日期不一样,并且相差恰好8小时。

b、Json字符串的日期不是用"yyyy-MM-dd HH:mm:ss"格式表示的。

2、问题分析

1)Json字符串中的日期是怎么表示的?

例如:"\/Date(942289871000+0800)\/",其中第一个数字表示自1970年1月1日午夜到指定日期的毫秒数;"+0800"部分可选,表示时区,默认为UTC。

所以,可以看出,JavaScriptSerializer类将本地时间序列化成的UTC的Json时间字符串,导致反序列化的时间为UTC时间。

在此,可以将反序列化后的时间转换成本地时间验证一下: Console.WriteLine(p2.Birthday.ToLocalTime()); 

运行结果: 1999/11/11 11:11:11 

3、解决方法

1)"\/Date(942289871000)\/"格式的时间替换成"yyyy-MM-dd HH:mm:ss"格式

代码如下:

 1 /// <summary>
 2 /// JSON序列化和反序列化辅助类
 3 /// </summary>
 4 public class JsonHelper
 5 {
 6     /// <summary>
 7     /// 将Json格式的时间字符串替换为"yyyy-MM-dd HH:mm:ss"格式的字符串
 8     /// </summary>
 9     /// <param name="json"></param>
10     /// <returns></returns>
11     public static string ReplaceJsonDateToDateString(string json)
12     {
13         return Regex.Replace(json, @"\\/Date\((\d+)\)\\/", match =>
14         {
15             DateTime dt = new DateTime(1970, 1, 1);
16             dt = dt.AddMilliseconds(long.Parse(match.Groups[1].Value));
17             dt = dt.ToLocalTime();
18             return dt.ToString("yyyy-MM-dd HH:mm:ss");
19         });
20     }
21 }
View Code
 1 Person p = new Person();
 2 p.ID = 1;
 3 p.Name = "zhangsan";
 4 p.Birthday = new DateTime(1999, 11, 11, 11, 11, 11);
 5 Console.WriteLine("序列化前的对象:"+p.ToString());
 6 
 7 JavaScriptSerializer jss = new JavaScriptSerializer();
 8 string json = jss.Serialize(p);
 9 Console.WriteLine("序列化后的JSON字符串:" + json);
10 
11 json = JsonHelper.ReplaceJsonDateToDateString(json);
12 Console.WriteLine("替换后的JSON字符串:" + json);
13 
14 Person p2 = jss.Deserialize<Person>(json);
15 Console.WriteLine("反序列化的对象:"+p2.ToString());
16 
17 Console.ReadLine();
View Code

运行结果:

序列化前的对象:ID:1;Name:zhangsan;Birthday:1999/11/1111:11:11 
序列化后的JSON字符串:{
"ID":1,"Name":"zhangsan","Birthday":"\/Date(942289871000)\/"}
替换后的JSON字符串:{
"ID":1,"Name":"zhangsan","Birthday":"1999-11-11 11:11:11"}
反序列化的对象:ID:
1;Name:zhangsan;Birthday:1999/11/1111:11:11

2)使用JsonConvert类进行序列化和反序列化

需要引用Json.NET程序集。代码如下:

 1 Person p = new Person();
 2 p.ID = 1;
 3 p.Name = "zhangsan";
 4 p.Birthday = new DateTime(1999, 11, 11, 11, 11, 11);
 5 Console.WriteLine("序列化前的对象:"+p.ToString());
 6 
 7 string json = JsonConvert.SerializeObject(p);
 8 Console.WriteLine("序列化后的JSON字符串:" + json);
 9 
10 Person p2 = JsonConvert.DeserializeObject<Person>(json);
11 Console.WriteLine("反序列化的对象:"+p2.ToString());
12 
13 Console.ReadLine();
View Code

运行结果:

原对象:ID:1;Name:zhangsan;Birthday:1999/11/11 11:11:11
序列化后的JSON字符串:{"ID":1,"Name":"zhangsan","Birthday":"1999-11-11T11:11:11"}
反序列化的对象:ID:1;Name:zhangsan;Birthday:1999/11/11 11:11:11

 

 

 

posted @ 2015-10-10 17:14  CCH-Taurus  阅读(1510)  评论(0编辑  收藏  举报