首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

.NET Framework 4 TimeSpan 格式化與剖析增強

     編輯:關於.NET

.NET 4 大幅強化 TimeSpan 的格式化與剖析支援,新增標準/自訂格式字串、IFormattable 實作、區域性感知、ParseExact/TryParseExact 等功能,與 DateTime 對齊。

.NET 3.5 與 4.0 格式化差異

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 等

區域性感知範例 (G 格式)

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  // 小數點改為逗號

.NET 3.5 剖析限制

TimeSpan.Parse/TryParse 僅支援固定格式:單一整數(視為天)、或至少 時:分。無法處理純小時、純分鐘、毫秒整數等格式。

.NET 4 剖析增強:ParseExact / TryParseExact

四個多載,支援標準/自訂格式字串陣列、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

OverflowException 處理策略

相容性考量:元件值超出範圍(時>23、分/秒>59)仍拋出 OverflowException。三種處理方式:

  1. 預處理:Int32.Parse 分解後呼叫建構函式(建構函式不檢查範圍)。缺點:所有輸入皆需預處理。
  2. Try-Catch:先 Parse,捕獲 OverflowException 再分解。缺點:例外處理開銷大。
  3. 最佳:TryParse 失敗再分解(推薦)

推薦實作:ParseIntervalWithoutOverflow

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>
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved