System.TimeSpan 结构
本文提供了此 API 参考文档的补充说明。
对象 TimeSpan 表示一个时间间隔(持续时间或已用时间),该时间间隔以正数或负天数、小时数、分钟数、秒数和秒分数为单位。 该 TimeSpan 结构还可用于表示一天的时间,但前提是时间与特定日期无关。 否则, DateTime 应改用或 DateTimeOffset 结构。 (有关使用 TimeSpan 结构反映一天的时间的详细信息,请参阅 “在 DateTime、DateTimeOffset、TimeSpan 和 TimeZoneInfo 之间进行选择”。)
注意
值 TimeSpan 表示时间间隔,可以表示为特定的天数、小时、分钟、秒和毫秒。 由于它表示不引用特定起点或终点的一般间隔,因此不能以年和月来表示,这两者都有可变天数。 它不同于一个 DateTime 值,该值表示不引用特定时区的日期和时间,或 DateTimeOffset 表示特定时间刻度的值。
结构用于度量持续时间的最大时间 TimeSpan 单位是一天。 时间间隔以天为单位来衡量一致性,因为以较大的时间单位(如月份和年份)的天数不同。
对象的值为 TimeSpan 等于所表示时间间隔的刻度数。 刻度等于 100 纳秒,即每秒 1,000 万秒。 对象的值 TimeSpan 可以介于 1 TimeSpan.MinValue 到 TimeSpan.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("{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
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: {0}", 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值由算术运算符和结构的算术运算符和TimeSpan方法DateTimeDateTimeOffset返回。
通过分析值的字符串表示形式 TimeSpan 。 可以使用 Parse 和 TryParse 方法将包含时间间隔的字符串转换为 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("'{0}' --> {1}", value, ts); } catch (FormatException) { Console.WriteLine("Unable to parse '{0}'", value); } catch (OverflowException) { Console.WriteLine("'{0}' is outside the range of a TimeSpan.", value); } } // 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'
此外,还可以通过调用ParseExact或TryParseExact方法定义要分析并转换为TimeSpan值的输入字符串的精确格式。
对 TimeSpan 值执行操作
可以使用和运算符或调用Add和SubtractionSubtract方法来添加和减去持续时间Addition。 还可以通过调用Compare和CompareToEquals方法来比较两个持续时间。 该TimeSpan结构还包括将DurationNegate时间间隔转换为正值和负值的方法,
值的范围 TimeSpan 是 MinValueMaxValue。
设置 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值的格式的代码<中最为常见。 以下示例成功设置 .NET Framework 3.5 及更低版本中的值的格式 TimeSpan ,但在 .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("{0} --> {1}", value, interval);
}
catch (FormatException)
{
Console.WriteLine("{0}: Bad Format", value);
}
catch (OverflowException)
{
Console.WriteLine("{0}: Overflow", value);
}
}
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.