共用方式為


System.TimeSpan 結構

本文提供此 API 參考文件的補充備註。

TimeSpan物件表示時間間隔(持續時間或經過的時間),以正或負的天數、小時、分鐘、秒和秒的分數計量。 結構 TimeSpan 也可以用來代表一天的時間,但只有當時間與特定日期無關時。 否則,應該使用 DateTimeDateTimeOffset 結構。 (如需使用 TimeSpan 結構反映一天時間的詳細資訊,請參閱 選擇 DateTime、DateTimeOffset、TimeSpan 和 TimeZoneInfo。)

備註

TimeSpan 代表時間間隔,而且可以表示為特定天數、小時、分鐘、秒和毫秒。 因為它代表著一個不參考特定起點或終點的一般時間間隔,所以不能用年和月來表示,因為這兩者的天數是不固定的。 它與 DateTime 值不同,該值代表日期和時間,而不參考特定時區,或 DateTimeOffset 代表特定時間刻度的值。

結構用來測量持續時間的最大時間 TimeSpan 單位是一天。 時間間隔是以天為單位來測量一致性,因為較大的時間單位天數,例如月和年,會有所不同。

物件的值 TimeSpan 是等於所表示時間間隔的刻度數。 一個刻度等於 100 奈秒,即一千萬分之一秒。 物件的值 TimeSpan 範圍可以從 到 TimeSpan.MinValueTimeSpan.MaxValue

具現化 TimeSpan 值

您可以透過數種方式具現化 TimeSpan 值:

  • 藉由呼叫其隱含無參數建構函式。 這會建立值為 TimeSpan.Zero的物件,如下列範例所示。

    TimeSpan interval = new TimeSpan();
    Console.WriteLine(interval.Equals(TimeSpan.Zero));    // Displays "True".
    
    let interval = TimeSpan()
    printfn $"{interval.Equals TimeSpan.Zero}"    // Displays "True".
    
    Dim interval As New TimeSpan()
    Console.WriteLine(interval.Equals(TimeSpan.Zero))     ' Displays "True".
    
  • 藉由呼叫其中一個明確的構造函數。 下列範例會將 TimeSpan 值初始化為指定的小時、分和秒數。

    TimeSpan interval = new TimeSpan(2, 14, 18);
    Console.WriteLine(interval.ToString());              
    
    // Displays "02:14:18".
    
    let interval = TimeSpan(2, 14, 18)
    printfn $"{interval}"              
    
    // Displays "02:14:18".
    
    Dim interval As New TimeSpan(2, 14, 18)
    Console.WriteLine(interval.ToString())                ' Displays "02:14:18".
    
  • 呼叫方法或執行傳回TimeSpan值的操作。 例如,您可以具現化代表兩個 TimeSpan 日期和時間值之間間隔的值,如下列範例所示。

    DateTime departure = new DateTime(2010, 6, 12, 18, 32, 0);
    DateTime arrival = new DateTime(2010, 6, 13, 22, 47, 0);
    TimeSpan travelTime = arrival - departure;  
    Console.WriteLine($"{arrival} - {departure} = {travelTime}");      
    
    // The example displays the following output:
    //       6/13/2010 10:47:00 PM - 6/12/2010 6:32:00 PM = 1.04:15:00
    
    let departure = DateTime(2010, 6, 12, 18, 32, 0)
    let arrival = DateTime(2010, 6, 13, 22, 47, 0)
    let travelTime = arrival - departure  
    printfn $"{arrival} - {departure} = {travelTime}"
    
    // The example displays the following output:
    //       6/13/2010 10:47:00 PM - 6/12/2010 6:32:00 PM = 1.04:15:00
    
    Dim departure As DateTime = #06/12/2010 6:32PM#
    Dim arrival As DateTime = #06/13/2010 10:47PM#
    Dim travelTime As TimeSpan = arrival - departure
    Console.WriteLine("{0} - {1} = {2}", arrival, departure, travelTime)
    ' The example displays the following output:
    '       6/13/2010 10:47:00 PM - 6/12/2010 6:32:00 PM = 1.04:15:00
    

    您也可以以此方式將 物件初始化 TimeSpan 為零時間值,如下列範例所示。

    Random rnd = new Random();
    
    TimeSpan timeSpent = TimeSpan.Zero;
    
    timeSpent += GetTimeBeforeLunch();
    timeSpent += GetTimeAfterLunch();
    
    Console.WriteLine($"Total time: {timeSpent}");
    
    TimeSpan GetTimeBeforeLunch()
    {
        return new TimeSpan(rnd.Next(3, 6), 0, 0);
    }
    
    TimeSpan GetTimeAfterLunch()
    {
        return new TimeSpan(rnd.Next(3, 6), 0, 0);
    }
    
    // The example displays output like the following:
    //        Total time: 08:00:00
    
    open System
    
    let rnd = Random()
    
    let getTimeBeforeLunch () =
        TimeSpan(rnd.Next(3, 6), 0, 0)
    
    let getTimeAfterLunch() =
        TimeSpan(rnd.Next(3, 6), 0, 0)
    
    do
        let timeSpent = TimeSpan.Zero
    
        let timeSpent = timeSpent + getTimeBeforeLunch ()
        let timeSpent = timeSpent + getTimeAfterLunch ()
    
        printfn $"Total time: {timeSpent}"
    
    
    // The example displays output like the following:
    //        Total time: 08:00:00
    
    Module Example
       Dim rnd As New Random()
       
       Public Sub Main()
          Dim timeSpent As TimeSpan = TimeSpan.Zero
    
          timeSpent += GetTimeBeforeLunch()
          timeSpent += GetTimeAfterLunch()
    
          Console.WriteLine("Total time: {0}", timeSpent)
       End Sub
       
       Private Function GetTimeBeforeLunch() As TimeSpan
          Return New TimeSpan(rnd.Next(3, 6), 0, 0)
       End Function
       
       Private Function GetTimeAfterLunch() As TimeSpan
          Return New TimeSpan(rnd.Next(3, 6), 0, 0)
       End Function
    End Module
    ' The example displays output like the following:
    '       Total time: 08:00:00
    

    TimeSpan值是由DateTimeDateTimeOffsetTimeSpan結構的算術運算元和方法所傳回。

  • 藉由剖析TimeSpan值的字串表示方式。 您可以使用 ParseTryParse 方法,將包含時間間隔的 TimeSpan 字串轉換成值。 下列範例會使用 Parse 方法,將字串陣列轉換成 TimeSpan 值。

    string[] values = { "12", "31.", "5.8:32:16", "12:12:15.95", ".12"};
    foreach (string value in values)
    {
       try {
          TimeSpan ts = TimeSpan.Parse(value);
          Console.WriteLine($"'{value}' --> {ts}");
       }
       catch (FormatException) {
          Console.WriteLine($"Unable to parse '{value}'");
       }
       catch (OverflowException) {
          Console.WriteLine($"'{value}' is outside the range of a TimeSpan.");
       }   
    }
    
    // The example displays the following output:
    //       '12' --> 12.00:00:00
    //       Unable to parse '31.'
    //       '5.8:32:16' --> 5.08:32:16
    //       '12:12:15.95' --> 12:12:15.9500000
    //       Unable to parse '.12'
    
    let values = [| "12"; "31."; "5.8:32:16"; "12:12:15.95"; ".12" |]
    for value in values do
        try
            let ts = TimeSpan.Parse value
            printfn $"'{value}' --> {ts}"
        with 
        | :? FormatException ->
            printfn $"Unable to parse '{value}'"
        | :? OverflowException ->
            printfn $"'{value}' is outside the range of a TimeSpan."
    
    // The example displays the following output:
    //       '12' --> 12.00:00:00
    //       Unable to parse '31.'
    //       '5.8:32:16' --> 5.08:32:16
    //       '12:12:15.95' --> 12:12:15.9500000
    //       Unable to parse '.12'
    
    Dim values() As String = {"12", "31.", "5.8:32:16", "12:12:15.95", ".12"}
    For Each value As String In values
        Try
            Dim ts As TimeSpan = TimeSpan.Parse(value)
            Console.WriteLine("'{0}' --> {1}", value, ts)
        Catch e As FormatException
            Console.WriteLine("Unable to parse '{0}'", value)
        Catch e As OverflowException
            Console.WriteLine("'{0}' is outside the range of a TimeSpan.", value)
        End Try
    Next
    ' The example displays the following output:
    '       '12' --> 12.00:00:00
    '       Unable to parse '31.'
    '       '5.8:32:16' --> 5.08:32:16
    '       '12:12:15.95' --> 12:12:15.9500000
    '       Unable to parse '.12'
    

    此外,您可以呼叫 TimeSpanParseExact 方法,定義要剖析和轉換成TryParseExact值的輸入字串精確格式。

對 TimeSpan 值執行作業

您可以使用 AdditionSubtraction 運算符,或呼叫 AddSubtract 方法來加法和減去時間持續時間。 您也可以呼叫 CompareCompareToEquals 方法來比較兩個時間持續時間。 結構 TimeSpan 也包含 DurationNegate 方法,可將時間間隔轉換為正值和負值。

值的範圍是從TimeSpanMinValue

格式化 TimeSpan 值

TimeSpan值可以表示為 [-]d:hh:mm:ss.ff,其中選擇性負號表示負時間間隔,d 元件為天,hh 是以24小時制為單位的小時,mm 為分鐘,ss 為秒,ff 為秒的小數部分。 也就是說,時間間隔可以是由正數或負數天數組成,不帶特定時間,或者是包含特定時間的天數,或者僅表示一天中的某個時間。

從 .NET Framework 4 開始,TimeSpan 結構透過其 ToString 方法的多載支援文化敏感的格式,將 TimeSpan 值轉換為其字串表示形式。 默認 TimeSpan.ToString() 方法會使用與舊版 .NET Framework 中的傳回值完全相同的不變異格式,傳回時間間隔。 TimeSpan.ToString(String) 重載可讓您指定格式字串,以定義時間間隔的字串表示。 重載TimeSpan.ToString(String, IFormatProvider)可讓您指定格式字串和時間間隔的字串表示中要使用之格式慣例的文化特性。 TimeSpan 支援標準和自定義格式字串。 (如需詳細資訊,請參閱 標準 TimeSpan 格式字串自訂 TimeSpan 格式字串。)不過,只有標準格式字串會區分文化特性。

還原舊版 TimeSpan 格式

在某些情況下,在 .NET Framework 3.5 和舊版中成功格式化 TimeSpan 值的程序代碼在 .NET Framework 4 中會失敗。 在程式碼中,這種情況最常見於呼叫 <TimeSpan_LegacyFormatMode> 元素 方法,以使用格式字串格式化 TimeSpan 值。 下列範例成功格式化TimeSpan值在.NET Framework 3.5及更早的版本中,但在.NET Framework 4和更新版本中引發例外狀況。 請注意,它會嘗試使用不支援的格式規範來格式化 TimeSpan 值,這在 .NET Framework 3.5 和舊版中會被忽略。

ShowFormattingCode();
// Output from .NET Framework 3.5 and earlier versions:
//       12:30:45
// Output from .NET Framework 4:
//       Invalid Format    

Console.WriteLine("---");

ShowParsingCode();
// Output:
//       000000006 --> 6.00:00:00

void ShowFormattingCode()
{
    TimeSpan interval = new TimeSpan(12, 30, 45);
    string output;
    try
    {
        output = String.Format("{0:r}", interval);
    }
    catch (FormatException)
    {
        output = "Invalid Format";
    }
    Console.WriteLine(output);
}

void ShowParsingCode()
{
    string value = "000000006";
    try
    {
        TimeSpan interval = TimeSpan.Parse(value);
        Console.WriteLine($"{value} --> {interval}");
    }
    catch (FormatException)
    {
        Console.WriteLine($"{value}: Bad Format");
    }
    catch (OverflowException)
    {
        Console.WriteLine($"{value}: Overflow");
    }
}
let showFormattingCode () =
    let interval = TimeSpan(12, 30, 45)
    try
        $"{interval:r}"
    with :? FormatException ->
        "Invalid Format"
    |> printfn "%s"

let showParsingCode () =
    let value = "000000006"
    try
        let interval = TimeSpan.Parse value
        printfn $"{value} --> {interval}"
    with
    | :? FormatException ->
        printfn $"{value}: Bad Format"
    | :? OverflowException ->
        printfn $"{value}: Overflow"

showFormattingCode ()
// Output from .NET Framework 3.5 and earlier versions:
//       12:30:45
// Output from .NET Framework 4:
//       Invalid Format    

printfn "---"

showParsingCode ()
// Output:
//       000000006 --> 6.00:00:00
Dim interval As New TimeSpan(12, 30, 45)
Dim output As String
Try
    output = String.Format("{0:r}", interval)
Catch e As FormatException
    output = "Invalid Format"
End Try
Console.WriteLine(output)
' Output from .NET Framework 3.5 and earlier versions:
'       12:30:45
' Output from .NET Framework 4:
'       Invalid Format

如果您無法修改程式代碼,您可以使用下列其中一種方式來還原 TimeSpan 值的舊格式:

  • 藉由建立包含 <TimeSpan_LegacyFormatMode> 元素的組態檔。 將這個項目的 enabled 屬性設定為 true 會根據每個應用程式還原舊版 TimeSpan 格式設定。

  • 當您建立應用程式域時,設定「NetFx40_TimeSpanLegacyFormatMode」相容性開關。 這會啟用個別應用程式域的舊版 TimeSpan 格式設定。 下列範例會建立使用舊版 TimeSpan 格式的應用程式域。

    using System;
    
    public class Example2
    {
        public static void Main()
        {
            AppDomainSetup appSetup = new AppDomainSetup();
            appSetup.SetCompatibilitySwitches(new string[] { "NetFx40_TimeSpanLegacyFormatMode" });
            AppDomain legacyDomain = AppDomain.CreateDomain("legacyDomain",
                                                            null, appSetup);
            legacyDomain.ExecuteAssembly("ShowTimeSpan.exe");
        }
    }
    
    open System
    
    let appSetup = AppDomainSetup()
    appSetup.SetCompatibilitySwitches [| "NetFx40_TimeSpanLegacyFormatMode" |]
    let legacyDomain = AppDomain.CreateDomain("legacyDomain", null, appSetup)
    legacyDomain.ExecuteAssembly "ShowTimeSpan.exe" |> ignore
    
    Module Example3
        Public Sub Main()
            Dim appSetup As New AppDomainSetup()
            appSetup.SetCompatibilitySwitches({"NetFx40_TimeSpanLegacyFormatMode"})
            Dim legacyDomain As AppDomain = AppDomain.CreateDomain("legacyDomain",
                                                                 Nothing, appSetup)
            legacyDomain.ExecuteAssembly("ShowTimeSpan.exe")
        End Sub
    End Module
    

    當下列程式代碼在新的應用程式域中執行時,它會還原為舊版 TimeSpan 格式設定行為。

    using System;
    
    public class Example3
    {
       public static void Main()
       {
          TimeSpan interval = DateTime.Now - DateTime.Now.Date;
          string msg = String.Format("Elapsed Time Today: {0:d} hours.",
                                     interval);
          Console.WriteLine(msg);
       }
    }
    // The example displays the following output:
    //       Elapsed Time Today: 01:40:52.2524662 hours.
    
    open System
    
    let interval = DateTime.Now - DateTime.Now.Date
    printfn $"Elapsed Time Today: {interval:d} hours."
    // The example displays the following output:
    //       Elapsed Time Today: 01:40:52.2524662 hours.
    
    Module Example4
        Public Sub Main()
            Dim interval As TimeSpan = Date.Now - Date.Now.Date
            Dim msg As String = String.Format("Elapsed Time Today: {0:d} hours.",
                                             interval)
            Console.WriteLine(msg)
        End Sub
    End Module
    ' The example displays output like the following:
    '       Elapsed Time Today: 01:40:52.2524662 hours.