11using Bing . Tests . Samples . Json ;
22using Bing . Tests . XUnitHelpers ;
33using Bing . Utils . Json ;
4+ using Bing . Utils . Json . Converters ;
45using Newtonsoft . Json ;
56
67namespace Bing . Utils . Tests . Json ;
@@ -10,6 +11,8 @@ namespace Bing.Utils.Tests.Json;
1011/// </summary>
1112public class JsonHelperTest : TestBase
1213{
14+ private static readonly DateTime DefaultDate = new ( 1900 , 1 , 1 ) ;
15+
1316 /// <summary>
1417 /// 初始化一个<see cref="TestBase"/>类型的实例
1518 /// </summary>
@@ -91,4 +94,145 @@ public void Test_ToObject()
9194 var customer = JsonHelper . ToObject < JsonTestSample > ( "{\" Name\" :\" a\" }" ) ;
9295 Assert . Equal ( "a" , customer . Name ) ;
9396 }
97+
98+ /// <summary>
99+ /// 测试 - 确保 DateTime 等于 1900-01-01 时,序列化结果为 null
100+ /// </summary>
101+ [ Fact ]
102+ public void Serialize_1900DateTime_ShouldBeNull ( )
103+ {
104+ var sample = new JsonDateTimeSample
105+ {
106+ ConfirmTime = DefaultDate ,
107+ OptionalTime = DefaultDate
108+ } ;
109+
110+ var json = JsonConvert . SerializeObject ( sample ) ;
111+ Output . WriteLine ( json ) ;
112+ Assert . Contains ( "\" ConfirmTime\" :null" , json ) ;
113+ Assert . Contains ( "\" OptionalTime\" :null" , json ) ;
114+ }
115+
116+ /// <summary>
117+ /// 测试 - 可空时间字段为 null 时,序列化结果应为 null;非 1900 日期应正常序列化
118+ /// </summary>
119+ [ Fact ]
120+ public void Serialize_NullOptionalTime_ShouldBeNull ( )
121+ {
122+ var sample = new JsonDateTimeSample
123+ {
124+ ConfirmTime = new DateTime ( 2025 , 1 , 1 ) ,
125+ OptionalTime = null
126+ } ;
127+
128+ var json = JsonConvert . SerializeObject ( sample ) ;
129+ Output . WriteLine ( json ) ;
130+ Assert . Contains ( "\" OptionalTime\" :null" , json ) ;
131+ Assert . Contains ( "\" ConfirmTime\" :\" 2025-01-01T00:00:00\" " , json ) ;
132+ }
133+
134+ /// <summary>
135+ /// 测试 - JSON 中为 null 的时间字段,反序列化应还原为 1900-01-01
136+ /// </summary>
137+ [ Fact ]
138+ public void Deserialize_NullJson_ShouldReturnDefaultDate ( )
139+ {
140+ var json = "{\" ConfirmTime\" :null,\" OptionalTime\" :null}" ;
141+ var sample = JsonConvert . DeserializeObject < JsonDateTimeSample > ( json ) ;
142+ Output . WriteLine ( json ) ;
143+ Assert . Equal ( DefaultDate , sample . ConfirmTime ) ;
144+ Assert . Equal ( DefaultDate , sample . OptionalTime ) ;
145+ }
146+
147+ /// <summary>
148+ /// 测试 - JSON 中为正常日期字符串时,能够正确反序列化为 DateTime 对象
149+ /// </summary>
150+ [ Fact ]
151+ public void Deserialize_NormalDate_ShouldParseCorrectly ( )
152+ {
153+ var json = "{\" ConfirmTime\" :\" 2023-12-12 10:30:00\" ,\" OptionalTime\" :\" 2023-12-12 10:30:00\" }" ;
154+
155+ var dto = JsonConvert . DeserializeObject < JsonDateTimeSample > ( json ) ;
156+
157+ var expected = new DateTime ( 2023 , 12 , 12 , 10 , 30 , 0 ) ;
158+ Output . WriteLine ( json ) ;
159+ Assert . Equal ( expected , dto . ConfirmTime ) ;
160+ Assert . Equal ( expected , dto . OptionalTime ) ;
161+ }
162+
163+ /// <summary>
164+ /// 测试 - JSON 中为正常日期字符串时,能够正确反序列化为 DateTime 对象
165+ /// </summary>
166+ [ Fact ]
167+ public void Deserialize_NormalDate_ShouldParseCorrectly_1 ( )
168+ {
169+ var json = "{\" ConfirmTime\" :\" 2023-12-12T10:30:00\" ,\" OptionalTime\" :\" 2023-12-12T10:30:00\" }" ;
170+
171+ var dto = JsonConvert . DeserializeObject < JsonDateTimeSample > ( json ) ;
172+
173+ var expected = new DateTime ( 2023 , 12 , 12 , 10 , 30 , 0 ) ;
174+ Output . WriteLine ( json ) ;
175+ Assert . Equal ( expected , dto . ConfirmTime ) ;
176+ Assert . Equal ( expected , dto . OptionalTime ) ;
177+ }
178+
179+ /// <summary>
180+ /// 测试 - JSON 中为正常日期字符串时,能够正确反序列化为 DateTime 对象
181+ /// </summary>
182+ [ Fact ]
183+ public void Deserialize_NormalDate_ShouldParseCorrectly_2 ( )
184+ {
185+ var json = "{\" ConfirmTime\" :\" 2023-12-12T10:30:00\" ,\" OptionalTime\" :\" 1900-01-01T00:00:00\" }" ;
186+
187+ var dto = JsonConvert . DeserializeObject < JsonDateTimeSample > ( json ) ;
188+
189+ var expected = new DateTime ( 2023 , 12 , 12 , 10 , 30 , 0 ) ;
190+ Output . WriteLine ( json ) ;
191+ Assert . Equal ( expected , dto . ConfirmTime ) ;
192+ Assert . Equal ( DefaultDate , dto . OptionalTime ) ;
193+ }
194+
195+ /// <summary>
196+ /// 测试 - JSON 中为正常日期字符串时,能够正确反序列化为 DateTime 对象
197+ /// </summary>
198+ [ Fact ]
199+ public void Deserialize_NormalDate_ShouldParseCorrectly_3 ( )
200+ {
201+ var json = "{\" ConfirmTime\" :\" 2023-12-12T10:30:00\" ,\" OptionalTime\" :null}" ;
202+
203+ var dto = JsonConvert . DeserializeObject < JsonDateTimeSample > ( json ) ;
204+
205+ var expected = new DateTime ( 2023 , 12 , 12 , 10 , 30 , 0 ) ;
206+ Output . WriteLine ( json ) ;
207+ Assert . Equal ( expected , dto . ConfirmTime ) ;
208+ Assert . Equal ( DefaultDate , dto . OptionalTime ) ;
209+ }
210+
211+ /// <summary>
212+ /// 测试 - 1900-01-01 的时间序列化为 null 后反序列化应还原为 1900-01-01
213+ /// </summary>
214+ [ Fact ]
215+ public void RoundTrip_Serialization_Deserialization_ShouldMaintainSemantics ( )
216+ {
217+ var original = new JsonDateTimeSample
218+ {
219+ ConfirmTime = DefaultDate ,
220+ OptionalTime = null
221+ } ;
222+
223+ var json = JsonConvert . SerializeObject ( original ) ;
224+ var deserialized = JsonConvert . DeserializeObject < JsonDateTimeSample > ( json ) ;
225+ Output . WriteLine ( json ) ;
226+ Assert . Equal ( DefaultDate , deserialized . ConfirmTime ) ;
227+ Assert . Equal ( DefaultDate , deserialized . OptionalTime ) ;
228+ }
229+
230+ private class JsonDateTimeSample
231+ {
232+ [ JsonConverter ( typeof ( DateTimeNullTo1900Converter ) ) ]
233+ public DateTime ConfirmTime { get ; set ; }
234+
235+ [ JsonConverter ( typeof ( DateTimeNullTo1900Converter ) ) ]
236+ public DateTime ? OptionalTime { get ; set ; }
237+ }
94238}
0 commit comments