[.Net Core 3.0+/.Net 5] System.Text.Json中時間格式化
- 2020 年 11 月 13 日
- 筆記
- .NET 5, .NET Core, c#, System.Text.Json
簡介
.Net Core 3.0開始全新推出了一個名為System.Text.Json
的Json解析庫,用於序列化和反序列化Json,此庫的設計是為了取代Json.Net(Newtonsoft.Json)
時間格式化的不足
System.Text.Json
的優點就不說了,來說一下不完善的地方,畢竟一個新事物出來,不可能十全十美的,用的最多的就是時間的格式化
官方文檔:在 System.Text.Json 中,具有內置支持的唯一格式是
ISO 8601-1:2019
,因為它被廣泛採用、意義明確並且可精確地進行往返。 若要使用任何其他格式,請創建自定義轉換器
ISO 8601-1:2019
通俗的說就是時間格式化為2020-11-11T21:08:18
。ISO 8601-1:2019
標準參考:ISO官網 | 百度百科 | wikipedia
但我們一般用的時候不想要這種格式,因為中間有一個T
,前端處理起來很麻煩,最好還是返回指定的時間格式,例如:yyyy-MM-dd
、yyyy-MM-dd HH:mm:ss
。
解決方案
既然官方不內置提供指定時間格式化的方式,那就沒辦法了嗎,查閱文檔發現,雖然無法簡單的實現功能,但是可以通過創建自定義轉換器來實現相應功能
文檔地址:微軟官方文檔
以下是一個自定義時間轉化器的完整實現:
public class DateTimeConverterUsingDateTimeParse : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return DateTime.Parse(reader.GetString());
}
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString("yyyy-MM-dd HH:mm:ss"));
}
}
使用
代碼看起來非常簡單是不是,只需要重寫Read
和Write
,但是我們只是寫了一個自定義轉換器,怎麼讓它生效呢,請往下看:
JsonSerializer.Serialize()
和JsonSerializer.Deserialize()
方法都接受一個JsonSerializerOptions
類型的配置項參數
在JsonSerializerOptions
添加Converters
就可以了
JsonSerializerOptions options = new JsonSerializerOptions()
{
Converters.Add(new DateTimeConverterUsingDateTimeParse())
}
string jsonString = JsonSerializer.Serialize(data, options);
至此,我們已經實現使用System.Text.Json
庫指定時間格式字符串進行序列化和反序列化,你甚至可以把yyyy-MM-dd HH:mm:ss
做成參數來更自由的指定格式化字符串
基準測試
但是凡事有利就有弊,官方文檔也說得很清楚了:
使用自定義轉換器與使用序列化程序的本機實現相比,此方法的性能大大降低
有人就想知道了,到底會影響多少性能呢,我進行了一項基準測試,序列化100000條數據,包含時間處理,模型如下:
public class Dto
{
public string Name { get; set; }
public string Phone { get; set; }
public DateTime DateTime { get; set; }
}
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042
Intel Core i7-6700K CPU 4.00GHz (Skylake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=5.0.100-rc.2.20479.15
[Host] : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT [AttachedDebugger]
DefaultJob : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT
System.Text.Json Version 5.0.0
Newtonsoft.Json Version 12.0.3
Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|
SystemTextJsonConverterDate | 67.36 ms | 0.489 ms | 0.458 ms | 2250.0000 | 750.0000 | 750.0000 | 52.15 MB |
SystemTextJson | 53.26 ms | 0.231 ms | 0.180 ms | 500.0000 | 500.0000 | 500.0000 | 48.67 MB |
NewtonsoftJsonConverterDate | 123.42 ms | 1.847 ms | 1.727 ms | 5800.0000 | 2200.0000 | 600.0000 | 51.61 MB |
NewtonsoftJson | 109.41 ms | 0.977 ms | 0.913 ms | 4800.0000 | 2000.0000 | 600.0000 | 50.82 MB |
結語
可以看到性能確實會有影響,但是可以忽略不計了,100000條才差10ms。
同時可以發現System.Text.Json
性能是Newtonsoft.Json
的兩倍
推薦大家以後在滿足需求的情況下盡量使用內置的System.Text.Json