using IRaCIS.Core.Domain.Share; using Microsoft.AspNetCore.Http; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using System; using System.Globalization; namespace IRaCIS.Core.API { /// /// 序列化,反序列化的时候,处理时间 时区转换 /// public class JSONTimeZoneConverter(IHttpContextAccessor _httpContextAccessor) : DateTimeConverterBase { private TimeZoneInfo _clientTimeZone; private string _dateFormat; public override bool CanConvert(Type objectType) { #region 设置语言格式化方式,放在构造函数里面做不到动态切换 var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US; if (!isEn_US) { // Chinese date format _dateFormat = "yyyy-MM-dd HH:mm:ss"; } else { // Default or English date format //_dateFormat = "MM/dd/yyyy HH:mm:ss"; _dateFormat = "yyyy-MM-dd HH:mm:ss"; } #endregion #region 获取当前请求的客户端时区 //var timeZoneId = "Etc/UTC"; var timeZoneId = "Asia/Shanghai"; var timeZoneIdHeader = _httpContextAccessor?.HttpContext?.Request?.Headers["TimeZoneId"]; if (timeZoneIdHeader is not null && !string.IsNullOrEmpty(timeZoneIdHeader.Value)) { timeZoneId = timeZoneIdHeader.Value; } _clientTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId); #endregion // 仅支持 DateTime 类型的转换 return objectType == typeof(DateTime) || objectType == typeof(DateTime?); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.Value == null) { return null; } DateTime dateTime; if (reader.ValueType == typeof(DateTime) || reader.ValueType == typeof(DateTime?)) { DateTime? nullableDateTime = reader.Value as DateTime?; if (nullableDateTime != null && nullableDateTime.HasValue) { dateTime = nullableDateTime.Value; } else { return null; } } else { if (DateTime.TryParse((string)reader.Value, out dateTime) == false) { return null; } } // 将客户端时间转换为服务器时区的时间 var serverZoneTime = TimeZoneInfo.ConvertTime(dateTime, _clientTimeZone, TimeZoneInfo.Local); return serverZoneTime; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { DateTime? nullableDateTime = value as DateTime?; if (nullableDateTime != null && nullableDateTime.HasValue) { //第一个参数默认使用系统本地时区 也就是应用服务器的时区 DateTime clientZoneTime = TimeZoneInfo.ConvertTime(nullableDateTime.Value, _clientTimeZone); //writer.WriteValue(clientZoneTime); writer.WriteValue(clientZoneTime.ToString(_dateFormat)); } else { writer.WriteNull(); } } } }