244 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			244 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C#
		
	
	
| 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
 | |
| {
 | |
|     /// <summary>
 | |
|     /// 序列化,反序列化的时候,处理时间 时区转换
 | |
|     /// </summary>
 | |
|     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();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|     }
 | |
| 
 | |
| 
 | |
|     public class DateOnlyUniversalJsonConverter : JsonConverter
 | |
|     {
 | |
|         private readonly string _format;
 | |
| 
 | |
|         public DateOnlyUniversalJsonConverter(string format = "yyyy-MM-dd")
 | |
|         {
 | |
|             _format = format;
 | |
|         }
 | |
| 
 | |
|         public override bool CanConvert(Type objectType)
 | |
|         {
 | |
|             return objectType == typeof(DateOnly) || objectType == typeof(DateOnly?);
 | |
|         }
 | |
| 
 | |
|         public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
 | |
|         {
 | |
|             if (value == null)
 | |
|             {
 | |
|                 writer.WriteValue(""); // null -> 空字符串
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             var date = (DateOnly)value;
 | |
|             if (date == default)
 | |
|             {
 | |
|                 writer.WriteValue(""); // default(DateOnly) -> 空字符串
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 writer.WriteValue(date.ToString(_format));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
 | |
|         {
 | |
|             var str = reader.TokenType == JsonToken.Null ? null : reader.Value?.ToString();
 | |
| 
 | |
|             if (string.IsNullOrWhiteSpace(str) || !DateOnly.TryParse(str, out var date))
 | |
|             {
 | |
|                 return objectType == typeof(DateOnly?) ? null : default(DateOnly);
 | |
|             }
 | |
| 
 | |
|             return date;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     #region 废弃
 | |
| 
 | |
|     public class MyDateTimeConverter : JsonConverter<DateTime>
 | |
|     {
 | |
|         public override DateTime ReadJson(JsonReader reader, Type objectType, DateTime existingValue, bool hasExistingValue, JsonSerializer serializer)
 | |
|         {
 | |
|             return reader.ReadAsDateTime().Value;
 | |
|         }
 | |
| 
 | |
|         public override void WriteJson(JsonWriter writer, DateTime value, JsonSerializer serializer)
 | |
|         {
 | |
|             var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
 | |
| 
 | |
|             string dateFormat;
 | |
|             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";
 | |
|             }
 | |
| 
 | |
|             writer.WriteValue(value.ToString(dateFormat));
 | |
| 
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public class MyNullableDateTimeConverter : JsonConverter<DateTime?>
 | |
|     {
 | |
|         public override DateTime? ReadJson(JsonReader reader, Type objectType, DateTime? existingValue, bool hasExistingValue, JsonSerializer serializer)
 | |
|         {
 | |
|             var val = reader.ReadAsDateTime();
 | |
|             return val;
 | |
|         }
 | |
| 
 | |
|         public override void WriteJson(JsonWriter writer, DateTime? value, JsonSerializer serializer)
 | |
|         {
 | |
|             var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
 | |
| 
 | |
|             string dateFormat;
 | |
|             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";
 | |
|             }
 | |
| 
 | |
|             if (value.HasValue)
 | |
|             {
 | |
|                 writer.WriteValue(value.Value.ToString(dateFormat));
 | |
| 
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 writer.WriteValue(default(DateTime?));
 | |
|             }
 | |
| 
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     #endregion
 | |
| }
 |