JavascriptSerializer序列化反序列化DateTime问题

JSON格式不直接支持日期和时间。
DateTime值值显示为“/Date(1522303200000+0800)/”形式的JSON字符串,其中第一个数字(在提供的示例中为 1522303200000)是GMT 时区中自1970年1月1日午夜以来按正常时间(非夏令时)经过的毫秒数。
该数字可以是负数,以表示之前的时间。
示例中包括“+0800”的部分可选,它指示该时间属于Local类型,即它在反序列化时应转换为本地时区。如果没有该部分,则会将时间反序列化为UTC时间。

使用JavascriptSerializer序列化时把时间转成了UTC时间,而反序列化时不会转回本地时间。导致时间少了8小时,如:

JavaScriptSerializer js = new JavaScriptSerializer();
Person p = new Person();
p.Name = "张三";
p.Age = 28;
p.LastLoginTime = new DateTime(2018, 3, 29, 14, 0, 0);
string jsonString = js.Serialize(p);
Console.WriteLine(jsonString);

Person p1 = js.Deserialize<Person>(jsonString);
Console.WriteLine(p1.LastLoginTime.ToString());
Console.ReadKey();

结果:

发现反序列化后的时间少了8小时。


解决办法:
1、调用的时候,使用ToLocalTime方法,转换成本地时间。
如:
Convert.ToDateTime(p1.LastLoginTime).ToLocalTime()

2、使用其他JSON序列化方法

(1)使用Newtonsoft.Json或者DataContractJsonSerializer封装工具类,如:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Data.Common;
using System.Reflection;
using System.Data;
using System.Collections;
using System.Web.Script.Serialization;
using System.Text.RegularExpressions;
using System.IO;
using System.Runtime.Serialization.Json;
using Newtonsoft.Json;
using System.Xml.Linq;
using Newtonsoft.Json.Converters;

namespace ConsoleApplication1
{
    public static class ConvertJson
    {
        public static T ParseObject<T>(string jsonStr)
        {
            using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonStr)))
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
                return (T)serializer.ReadObject(ms);

            }
        }

        public static string ParseJson<T>(T obj)
        {
            string strR = string.Empty;
            using (MemoryStream ms = new MemoryStream())
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
                serializer.WriteObject(ms, obj);
                //byte[] buffer = new byte[ms.Length];
                //ms.Read(buffer, 0, buffer.Length);
                //strR= Encoding.Default.GetString(buffer);

                using (StreamReader sr = new StreamReader(ms, Encoding.UTF8))
                {
                    ms.Position = 0;
                    strR = sr.ReadToEnd();
                }
            }
            return strR;
        }

        public static T JsonParse<T>(string json)
        {
            return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(json);
        }

        public static object JsonToObject(string jsonString, Type type)
        {
            return JsonConvert.DeserializeObject(jsonString, type);
        }

        public static string ObjectToJson(object obj)
        {
            return JsonConvert.SerializeObject(obj, Formatting.None, new JsonSerializerSettings { Converters = new List<JsonConverter>() { new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" } } });
        }

    }
}

 使用示例:

Person p = new Person();
p.Name = "张三";
p.Age = 28;
p.LastLoginTime = new DateTime(2018, 3, 29, 14, 0, 0);
string jsonString = ConvertJson.ObjectToJson(p);
string jsonString1 = ConvertJson.ParseJson<Person>(p);
Console.WriteLine(jsonString);
Console.WriteLine(jsonString1);

Person p1 = (Person)ConvertJson.JsonToObject(jsonString, typeof(Person));
Person p2 = ConvertJson.ParseObject<Person>(jsonString1);
Console.WriteLine(p1.LastLoginTime.ToString());
Console.WriteLine(p2.LastLoginTime.ToString());

Console.ReadKey();

 结果:


(2)其他自定义工具类,如:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;  

namespace ConsoleApplication1
{
    /// <summary>    
    /// JSON序列化和反序列化辅助类    
    /// </summary>    
    public class JsonHelper
    {
        /// <summary>    
        /// JSON序列化    
        /// </summary>    
        public static string JsonSerializer<T>(T t)
        {
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
            MemoryStream ms = new MemoryStream();
            ser.WriteObject(ms, t);
            string jsonString = Encoding.UTF8.GetString(ms.ToArray());
            ms.Close();
            //替换Json的Date字符串    
            string p = @"///Date/((/d+)/+/d+/)///"; 
            MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertJsonDateToDateString);
            Regex reg = new Regex(p);
            jsonString = reg.Replace(jsonString, matchEvaluator);
            return jsonString;
        }
        /// <summary>    
        /// JSON反序列化    
        /// </summary>    
        public static T JsonDeserialize<T>(string jsonString)
        {
            //将"yyyy-MM-dd HH:mm:ss"格式的字符串转为"//Date(1294499956278+0800)//"格式    
            string p = @"/d{4}-/d{2}-/d{2}/s/d{2}:/d{2}:/d{2}";
            MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertDateStringToJsonDate);
            Regex reg = new Regex(p);
            jsonString = reg.Replace(jsonString, matchEvaluator);
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
            MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
            T obj = (T)ser.ReadObject(ms);
            return obj;
        }

        /// <summary>    
        /// 将Json序列化的时间由/Date(1294499956278+0800)转为字符串    
        /// </summary>    
        private static string ConvertJsonDateToDateString(Match m)
        {
            string result = string.Empty;
            DateTime dt = new DateTime(1970, 1, 1);
            dt = dt.AddMilliseconds(long.Parse(m.Groups[1].Value));
            dt = dt.ToLocalTime();
            result = dt.ToString("yyyy-MM-dd HH:mm:ss");
            return result;
        }
        /// <summary>    
        /// 将时间字符串转为Json时间    
        /// </summary>    
        private static string ConvertDateStringToJsonDate(Match m)
        {
            string result = string.Empty;
            DateTime dt = DateTime.Parse(m.Groups[0].Value);
            dt = dt.ToUniversalTime();
            TimeSpan ts = dt - DateTime.Parse("1970-01-01");
            result = string.Format("///Date({0}+0800)///", ts.TotalMilliseconds);
            return result;
        }
    }  
}

使用示例:

Person p = new Person();
p.Name = "张三";
p.Age = 28;
p.LastLoginTime = DateTime.Now;
string jsonString = JsonHelper.JsonSerializer<Person>(p);
Console.WriteLine(jsonString);

Person p1 = JsonHelper.JsonDeserialize<Person>(jsonString);
Console.WriteLine(Convert.ToDateTime(p1.LastLoginTime).ToLocalTime());
Console.ReadKey();

 结果:

 

参考:
https://www.cnblogs.com/talentzemin/p/5691521.html
https://blog.csdn.net/cncdns/article/details/6164389

 

posted @ 2018-03-29 15:18  skybirdzw  阅读(1345)  评论(0)    收藏  举报