• C# json序列化实体时,时间戳转Datetime


    在日常开发中,对接接口时,如果对方返回的时间字段是时间戳,而C#这边的接收实体是DateTime类型,在序列化Json时,报错:Error setting value to 'ModifyTime' on 'ArticleTableModel'.

    解决方案:

    在DateTime字段添加注解,具体代码如下:

    1. ///
    2. /// 接收结果实体
    3. ///
    4. public class ArticleTableModel
    5. {
    6. ///
    7. /// 最后修改时间
    8. ///
    9. [JsonConverter(typeof(MicrosecondEpochConverter))]
    10. public DateTime? ModifyTime { get; set; }
    11. }
    12. /
    13. public class MicrosecondEpochConverter : DateTimeConverterBase
    14. {
    15. private static readonly DateTime _epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    16. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    17. {
    18. writer.WriteRawValue(((DateTime)value - _epoch).TotalMilliseconds + "");
    19. }
    20. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    21. {
    22. if (reader.Value == null) { return null; }
    23. //return _epoch.AddMilliseconds((long)reader.Value / 1000d);
    24. long.TryParse(reader.Value.ToString(), out long timestampes);
    25. long mill = 0;
    26. if (timestampes <= 0)
    27. {
    28. DateTime.TryParse(reader.Value.ToString(), out DateTime currentTime);
    29. mill = CommonTimeStamp.GetTimeStampMilliseconds(currentTime);
    30. }
    31. else
    32. {
    33. mill = Convert.ToInt64(reader.Value);
    34. }
    35. return _epoch.AddMilliseconds(mill);
    36. }
    37. }
    38. ///
    39. /// 时间戳操作类
    40. ///
    41. public class CommonTimeStamp
    42. {
    43. #region 标准北京时间(1970年01月01日08时00分00秒)
    44. #region 10位时间戳转换(秒级)
    45. ///
    46. /// 【秒级】获取时间(北京时间)
    47. ///
    48. /// 10位时间戳
    49. public static DateTime GetDateTimeSeconds(long timestamp)
    50. {
    51. long begtime = timestamp * 10000000;
    52. DateTime dt_1970 = new DateTime(1970, 1, 1, 8, 0, 0);
    53. long tricks_1970 = dt_1970.Ticks;//1970年1月1日刻度
    54. long time_tricks = tricks_1970 + begtime;//日志日期刻度
    55. DateTime dt = new DateTime(time_tricks);//转化为DateTime
    56. return dt;
    57. }
    58. ///
    59. /// 【秒级】生成10位时间戳(北京时间)
    60. ///
    61. /// 时间
    62. public static long GetTimeStampSeconds(DateTime dt)
    63. {
    64. DateTime dateStart = new DateTime(1970, 1, 1, 8, 0, 0);
    65. return Convert.ToInt64((dt - dateStart).TotalSeconds);
    66. }
    67. #endregion
    68. #region 13位时间戳转换(毫秒级)
    69. ///
    70. /// 【毫秒级】获取时间(北京时间)
    71. ///
    72. /// 10位时间戳
    73. public static DateTime GetDateTimeMilliseconds(long timestamp)
    74. {
    75. long begtime = timestamp * 10000;
    76. DateTime dt_1970 = new DateTime(1970, 1, 1, 8, 0, 0);
    77. long tricks_1970 = dt_1970.Ticks;//1970年1月1日刻度
    78. long time_tricks = tricks_1970 + begtime;//日志日期刻度
    79. DateTime dt = new DateTime(time_tricks);//转化为DateTime
    80. return dt;
    81. }
    82. ///
    83. /// 【毫秒级】生成13位时间戳(北京时间)
    84. ///
    85. /// 时间
    86. public static long GetTimeStampMilliseconds(DateTime dt)
    87. {
    88. DateTime dateStart = new DateTime(1970, 1, 1, 8, 0, 0);
    89. return Convert.ToInt64((dt - dateStart).TotalMilliseconds);
    90. }
    91. #endregion
    92. #endregion
    93. #region 标准格林威治时间(Unix时间戳:1970年01月01日00时00分00秒)
    94. #region 10位时间戳转换(秒级)
    95. ///
    96. /// 【秒级】获取时间(格林威治时间)
    97. ///
    98. /// 10位时间戳
    99. public static DateTime GetUnixDateTimeSeconds(long timestamp)
    100. {
    101. long begtime = timestamp * 10000000;
    102. DateTime dt_1970 = new DateTime(1970, 1, 1, 0, 0, 0);
    103. long tricks_1970 = dt_1970.Ticks;//1970年1月1日刻度
    104. long time_tricks = tricks_1970 + begtime;//日志日期刻度
    105. DateTime dt = new DateTime(time_tricks);//转化为DateTime
    106. return dt;
    107. }
    108. ///
    109. /// 【秒级】生成10位时间戳(格林威治时间)
    110. ///
    111. /// 时间
    112. public static long GetUnixTimeStampSeconds(DateTime dt)
    113. {
    114. DateTime dateStart = new DateTime(1970, 1, 1, 0, 0, 0);
    115. return Convert.ToInt64((dt - dateStart).TotalSeconds);
    116. }
    117. #endregion
    118. #region 13位时间戳转换(毫秒级)
    119. ///
    120. /// 【毫秒级】获取时间(格林威治时间)
    121. ///
    122. /// 10位时间戳
    123. public static DateTime GetUnixDateTimeMilliseconds(long timestamp)
    124. {
    125. long begtime = timestamp * 10000;
    126. DateTime dt_1970 = new DateTime(1970, 1, 1, 0, 0, 0);
    127. long tricks_1970 = dt_1970.Ticks;//1970年1月1日刻度
    128. long time_tricks = tricks_1970 + begtime;//日志日期刻度
    129. DateTime dt = new DateTime(time_tricks);//转化为DateTime
    130. return dt;
    131. }
    132. ///
    133. /// 【毫秒级】生成13位时间戳(格林威治时间)
    134. ///
    135. /// 时间
    136. public static long GetUnixTimeStampMilliseconds(DateTime dt)
    137. {
    138. DateTime dateStart = new DateTime(1970, 1, 1, 0, 0, 0);
    139. return Convert.ToInt64((dt - dateStart).TotalMilliseconds);
    140. }
    141. #endregion
    142. #endregion
    143. }

    引入nuget包:

    Newtonsoft.Json

    以上就是通过注解的方式处理序列化异常,除了使用以上方式外,还可以使用C#实体字段中的get set 属性进行处理。

  • 相关阅读:
    DEA一直updating index,这样无法使用其内部各种方法跳转,而且持续时间特别长
    【网络服务&数据库教程】07 ELK日志解决方案
    Linux基础篇-文件句柄数修改
    大模型之Chat Markup Language
    草莓熊python turtle绘图代码
    【JavaSE】Java基础语法(二十三):递归与数组的高级操作
    Linux查询文件和字符串命令
    探索 DTD 在 XML 中的作用及解析:深入理解文档类型定义
    navicat无法连接mysql超详细处理方法
    Echarts河北地图缺少雄安新区(合并、调整地图边缘)的解决办法
  • 原文地址:https://blog.csdn.net/suxuelian/article/details/128129556