.NET 4 大幅強化 TimeSpan 的格式化與剖析支援,新增標準/自訂格式字串、IFormattable 實作、區域性感知、ParseExact/TryParseExact 等功能,與 DateTime 對齊。
3.5:僅支援無參數 ToString(),固定格式(至少 時:分:秒,非零含天,含小數秒則 7 位刻度)。
4.0 新增:
ToString(string format)、ToString(string format, IFormatProvider provider)IFormattable,支援 String.Format、Console.WriteLine 等複合格式化c(固定)、t/T(短/長時間)、g/G(區域性感知一般格式)d、h、m、s、f、F 等TimeSpan interval = new TimeSpan(1, 12, 42, 30, 566); // 1天 12:42:30.566
CultureInfo[] cultures = { new CultureInfo("en-US"), new CultureInfo("fr-FR") };
foreach (var c in cultures)
Console.WriteLine($"{c}: {interval.ToString("G", c)}");
en-US: 1:12:42:30.5660000
fr-FR: 1:12:42:30,5660000 // 小數點改為逗號
TimeSpan.Parse/TryParse 僅支援固定格式:單一整數(視為天)、或至少 時:分。無法處理純小時、純分鐘、毫秒整數等格式。
四個多載,支援標準/自訂格式字串陣列、IFormatProvider、TimeSpanStyles。
string[] formats = { "hh", "%h", @"h\:mm", @"hh\:mm", @"d\.hh\:mm\:ss", "fffff", "hhmm" };
string[] values = { "16", "1", "16:03", "1:12", "1.13:34:15", "41237", "0609" };
foreach (var v in values) {
try {
var ts = TimeSpan.ParseExact(v, formats, null);
Console.WriteLine($"Converted '{v}' to {ts}");
} catch (FormatException) { Console.WriteLine($"Invalid format: {v}"); }
}
Converted '16' to 16:00:00
Converted '1' to 01:00:00
Converted '16:03' to 16:03:00
Converted '1:12' to 01:12:00
Converted '1.13:34:15' to 1.13:34:15
Converted '41237' to 00:00:00.4123700 // 5位數視為毫秒
Converted '0609' to 06:09:00
Parse(String):單一整數 永遠視為天數("16" → 16 天)ParseExact:依自訂格式決定("%h" → 16 小時,"fffff" → 41237 毫秒)string[] formats = { "%h", "hh", "fff", "ffff", "fffff" }; // 1-5 位數對應不同單位
string[] values = { "3", "17", "192", "3451", "79123", "01233" };
foreach (var v in values) {
if (TimeSpan.TryParseExact(v, formats, null, out var ts))
Console.WriteLine($"Converted '{v}' to {ts}");
else
Console.WriteLine($"Unable to parse {v}.");
}
Converted '3' to 03:00:00 // 1位 = 小時
Converted '17' to 17:00:00 // 2位 = 小時
Converted '192' to 00:00:00.1920000 // 3位 = 毫秒
Converted '3451' to 00:00:00.3451000 // 4位 = 毫秒
Converted '79123' to 00:00:00.7912300 // 5位 = 毫秒
Converted '01233' to 00:00:00.0123300
相容性考量:元件值超出範圍(時>23、分/秒>59)仍拋出 OverflowException。三種處理方式:
Int32.Parse 分解後呼叫建構函式(建構函式不檢查範圍)。缺點:所有輸入皆需預處理。Parse,捕獲 OverflowException 再分解。缺點:例外處理開銷大。private static TimeSpan ParseIntervalWithoutOverflow(string value) {
if (TimeSpan.TryParse(value, out var interval)) return interval;
// 分解字串元件
var parts = value.Split('.', ':');
int offset = 0, days = 0, hours = 0, minutes = 0, seconds = 0, ms = 0;
// 偵測是否含天數 (格式 d.hh:mm:ss)
if (value.IndexOf('.') >= 0 && value.IndexOf('.') < value.IndexOf(':')) {
offset = 1;
days = int.Parse(parts[0]);
}
hours = int.Parse(parts[offset]);
minutes = int.Parse(parts[offset + 1]);
if (parts.Length >= offset + 3) seconds = int.Parse(parts[offset + 2]);
if (parts.Length >= offset + 4) ms = int.Parse(parts[offset + 3]);
return new TimeSpan(days, hours, minutes, seconds, ms); // 建構函式接受超範圍值
}
string[] values = { "37:16:45.33", "0:128:16.324", "120:08" };
// 輸出:
// '37:16:45.33' --> 1.13:16:45.0330000 (37小時 = 1天13小時)
// '0:128:16.324' --> 02:08:16.3240000 (128分 = 2小時8分)
// '120:08' --> 5.00:08:00 (120小時 = 5天)
.NET 4 實作 IFormattable 導致舊代碼 String.Format("{0:r}", timespan) 拋出 FormatException(r 非支援格式)。
修復:移除無效格式字串、或啟用舊模式:
<configuration>
<runtime>
<TimeSpan_LegacyFormatMode enabled="true"/>
</runtime>
</configuration>