通过


实例化 DateTimeOffset 对象

DateTimeOffset 结构提供了许多创建新 DateTimeOffset 值的方法。 其中许多值直接与可用于实例化新 DateTime 值的方法相对应,通过增强功能可以指定日期和时间值与协调世界时(UTC)的偏移量。 具体而言,可以通过以下方式实例化 DateTimeOffset 值:

  • 通过使用日期和时间文本。

  • 通过调用 DateTimeOffset 构造函数。

  • 通过将某个值隐式转换为DateTimeOffset值。

  • 通过分析日期和时间的字符串表示形式。

本主题提供更详细的代码示例,这些示例说明了这些实例化新 DateTimeOffset 值的方法。

日期和时间文本

对于支持它的语言,实例化 DateTime 值的最常见方法之一是将日期和时间作为硬编码的文本值提供。 例如,以下 Visual Basic 代码创建一个 DateTime 值为 2008 年 5 月 1 日上午 8:06:32 的对象。

Dim literalDate1 As Date = #05/01/2008 8:06:32 AM#
Console.WriteLine(literalDate1.ToString())
' Displays:
'              5/1/2008 8:06:32 AM

DateTimeOffset 值还可以通过日期和时间字面量初始化,前提是使用的语言支持 DateTime 字面量。 例如,以下 Visual Basic 代码创建一个 DateTimeOffset 对象。

Dim literalDate As DateTimeOffset = #05/01/2008 8:06:32 AM#
Console.WriteLine(literalDate.ToString())
' Displays:
'              5/1/2008 8:06:32 AM -07:00

如控制台输出所示,以这种方式创建的DateTimeOffset值被分配给本地时区的偏移量。 这意味着, DateTimeOffset 如果代码在不同的计算机上运行,则使用字符文本分配的值不会标识单个时间点。

DateTimeOffset 构造函数

DateTimeOffset 类型定义六个构造函数。 有四个直接与DateTime构造函数对应,并且包含一个类型为TimeSpan的附加参数,该参数用于定义日期和时间相对于UTC的偏移量。 通过这些属性,可以根据其各个日期和时间组件的值定义值 DateTimeOffset 。 例如,以下代码使用以下四个构造函数来实例化 DateTimeOffset 值相同的 5/1/2008 8:06:32 +01:00 的对象。

DateTimeOffset dateAndTime;

// Instantiate date and time using years, months, days,
// hours, minutes, and seconds
dateAndTime = new DateTimeOffset(2008, 5, 1, 8, 6, 32,
                                 new TimeSpan(1, 0, 0));
Console.WriteLine(dateAndTime);
// Instantiate date and time using years, months, days,
// hours, minutes, seconds, and milliseconds
dateAndTime = new DateTimeOffset(2008, 5, 1, 8, 6, 32, 545,
                                 new TimeSpan(1, 0, 0));
Console.WriteLine($"{dateAndTime.ToString("G")} {dateAndTime.ToString("zzz")}");

// Instantiate date and time using Persian calendar with years,
// months, days, hours, minutes, seconds, and milliseconds
dateAndTime = new DateTimeOffset(1387, 2, 12, 8, 6, 32, 545,
                                 new PersianCalendar(),
                                 new TimeSpan(1, 0, 0));
// Note that the console output displays the date in the Gregorian
// calendar, not the Persian calendar.
Console.WriteLine($"{dateAndTime.ToString("G")} {dateAndTime.ToString("zzz")}");

// Instantiate date and time using number of ticks
// 05/01/2008 8:06:32 AM is 633,452,259,920,000,000 ticks
dateAndTime = new DateTimeOffset(633452259920000000, new TimeSpan(1, 0, 0));
Console.WriteLine(dateAndTime);
// The example displays the following output to the console:
//       5/1/2008 8:06:32 AM +01:00
//       5/1/2008 8:06:32 AM +01:00
//       5/1/2008 8:06:32 AM +01:00
//       5/1/2008 8:06:32 AM +01:00
Dim dateAndTime As DateTimeOffset

' Instantiate date and time using years, months, days, 
' hours, minutes, and seconds
dateAndTime = New DateTimeOffset(2008, 5, 1, 8, 6, 32, _
                                 New TimeSpan(1, 0, 0))
Console.WriteLine(dateAndTime)
' Instantiate date and time using years, months, days,
' hours, minutes, seconds, and milliseconds
dateAndTime = New DateTimeOffset(2008, 5, 1, 8, 6, 32, 545, _
                                 New TimeSpan(1, 0, 0))
Console.WriteLine("{0} {1}", dateAndTime.ToString("G"), _
                             dateAndTime.ToString("zzz"))

' Instantiate date and time using Persian calendar with years,
' months, days, hours, minutes, seconds, and milliseconds
dateAndTime = New DateTimeOffset(1387, 2, 12, 8, 6, 32, 545, New PersianCalendar, New TimeSpan(1, 0, 0))
' Note that the console output displays the date in the Gregorian
' calendar, not the Persian calendar. 
Console.WriteLine("{0} {1}", dateAndTime.ToString("G"), _
                             dateAndTime.ToString("zzz"))

' Instantiate date and time using number of ticks
' 05/01/2008 8:06:32 AM is 633,452,259,920,000,000 ticks
dateAndTime = New DateTimeOffset(633452259920000000, New TimeSpan(1, 0, 0))
Console.WriteLine(dateAndTime)
' The example displays the following output to the console:
'       5/1/2008 8:06:32 AM +01:00
'       5/1/2008 8:06:32 AM +01:00
'       5/1/2008 8:06:32 AM +01:00
'       5/1/2008 8:06:32 AM +01:00

请注意,当用PersianCalendar对象作为构造函数的参数之一实例化出DateTimeOffset对象时,该对象的值在显示到控制台时,会以公历日期而非波斯历日期的形式表达。 若要使用波斯日历输出日期,请参阅主题中的 PersianCalendar 示例。

另外两个 DateTimeOffset 构造函数从值 DateTime 创建对象。 这些中的第一个有一个参数,即< c0 />值,要转换为< c1 />值。 生成的 DateTimeOffset 值的偏移量取决于 Kind 构造函数的单个参数的属性。 如果其值为 DateTimeKind.Utc,则偏移量设置为等于 TimeSpan.Zero。 否则,其偏移量设置为等于本地时区的偏移量。 以下示例演示如何使用此构造函数来实例化 DateTimeOffset 表示 UTC 和本地时区的对象:

// Declare date; Kind property is DateTimeKind.Unspecified
DateTime sourceDate = new DateTime(2008, 5, 1, 8, 30, 0);
DateTimeOffset targetTime;

// Instantiate a DateTimeOffset value from a UTC time
DateTime utcTime = DateTime.SpecifyKind(sourceDate, DateTimeKind.Utc);
targetTime = new DateTimeOffset(utcTime);
Console.WriteLine(targetTime);
// Displays 5/1/2008 8:30:00 AM +00:00
// Because the Kind property is DateTimeKind.Utc,
// the offset is TimeSpan.Zero.

// Instantiate a DateTimeOffset value from a UTC time with a zero offset
targetTime = new DateTimeOffset(utcTime, TimeSpan.Zero);
Console.WriteLine(targetTime);
// Displays 5/1/2008 8:30:00 AM +00:00
// Because the Kind property is DateTimeKind.Utc,
// the call to the constructor succeeds

// Instantiate a DateTimeOffset value from a UTC time with a negative offset
try
{
   targetTime = new DateTimeOffset(utcTime, new TimeSpan(-2, 0, 0));
   Console.WriteLine(targetTime);
}
catch (ArgumentException)
{
   Console.WriteLine($"Attempt to create DateTimeOffset value from {targetTime} failed.");
}
// Throws exception and displays the following to the console:
//   Attempt to create DateTimeOffset value from 5/1/2008 8:30:00 AM +00:00 failed.

// Instantiate a DateTimeOffset value from a local time
DateTime localTime = DateTime.SpecifyKind(sourceDate, DateTimeKind.Local);
targetTime = new DateTimeOffset(localTime);
Console.WriteLine(targetTime);
// Displays 5/1/2008 8:30:00 AM -07:00
// Because the Kind property is DateTimeKind.Local,
// the offset is that of the local time zone.

// Instantiate a DateTimeOffset value from an unspecified time
targetTime = new DateTimeOffset(sourceDate);
Console.WriteLine(targetTime);
// Displays 5/1/2008 8:30:00 AM -07:00
// Because the Kind property is DateTimeKind.Unspecified,
// the offset is that of the local time zone.
' Declare date; Kind property is DateTimeKind.Unspecified
Dim sourceDate As Date = #5/1/2008 8:30 AM#
Dim targetTime As DateTimeOffset

' Instantiate a DateTimeOffset value from a UTC time 
Dim utcTime As Date = Date.SpecifyKind(sourceDate, DateTimeKind.Utc)
targetTime = New DateTimeOffset(utcTime)
Console.WriteLine(targetTime)
' Displays 5/1/2008 8:30:00 AM +00:00
' Because the Kind property is DateTimeKind.Utc, 
' the offset is TimeSpan.Zero.


' Instantiate a DateTimeOffset value from a local time
Dim localTime As Date = Date.SpecifyKind(sourceDate, DateTimeKind.Local)
targetTime = New DateTimeOffset(localTime)
Console.WriteLine(targetTime)
' Displays 5/1/2008 8:30:00 AM -07:00
' Because the Kind property is DateTimeKind.Local, 
' the offset is that of the local time zone.

' Instantiate a DateTimeOffset value from an unspecified time
targetTime = New DateTimeOffset(sourceDate)
Console.WriteLine(targetTime)
' Displays 5/1/2008 8:30:00 AM -07:00
' Because the Kind property is DateTimeKind.Unspecified, 
' the offset is that of the local time zone.

'

注释

调用具有单个DateTime参数的DateTimeOffset构造函数的重载等效于执行DateTime值到DateTimeOffset值的隐式转换。

DateTimeOffset值创建DateTime对象的第二个构造函数包含两个参数:DateTime要转换的值,以及TimeSpan用于表示日期和时间与 UTC 偏移的值。 此偏移值必须与构造函数的第一个参数的Kind属性相对应,否则将抛出ArgumentExceptionKind如果第一个参数的属性是DateTimeKind.Utc,则第二个参数的值必须是 TimeSpan.ZeroKind如果第一个参数的属性是DateTimeKind.Local,则第二个参数的值必须是本地系统的时区的偏移量。 Kind如果第一个参数的属性为DateTimeKind.Unspecified,则偏移量可以是任何有效值。 下面的代码演示了对此构造函数的调用,用于将DateTime转换为DateTimeOffset值。

DateTime sourceDate = new DateTime(2008, 5, 1, 8, 30, 0);
DateTimeOffset targetTime;

// Instantiate a DateTimeOffset value from a UTC time with a zero offset.
DateTime utcTime = DateTime.SpecifyKind(sourceDate, DateTimeKind.Utc);
targetTime = new DateTimeOffset(utcTime, TimeSpan.Zero);
Console.WriteLine(targetTime);
// Displays 5/1/2008 8:30:00 AM +00:00
// Because the Kind property is DateTimeKind.Utc,
// the call to the constructor succeeds

// Instantiate a DateTimeOffset value from a UTC time with a non-zero offset.
try
{
   targetTime = new DateTimeOffset(utcTime, new TimeSpan(-2, 0, 0));
   Console.WriteLine(targetTime);
}
catch (ArgumentException)
{
   Console.WriteLine($"Attempt to create DateTimeOffset value from {utcTime} failed.");
}
// Throws exception and displays the following to the console:
//   Attempt to create DateTimeOffset value from 5/1/2008 8:30:00 AM failed.

// Instantiate a DateTimeOffset value from a local time with
// the offset of the local time zone
DateTime localTime = DateTime.SpecifyKind(sourceDate, DateTimeKind.Local);
targetTime = new DateTimeOffset(localTime,
                                TimeZoneInfo.Local.GetUtcOffset(localTime));
Console.WriteLine(targetTime);
// Displays 5/1/2008 8:30:00 AM -07:00
// Because the Kind property is DateTimeKind.Local and the offset matches
// that of the local time zone, the call to the constructor succeeds.

// Instantiate a DateTimeOffset value from a local time with a zero offset.
try
{
   targetTime = new DateTimeOffset(localTime, TimeSpan.Zero);
   Console.WriteLine(targetTime);
}
catch (ArgumentException)
{
   Console.WriteLine($"Attempt to create DateTimeOffset value from {localTime} failed.");
}
// Throws exception and displays the following to the console:
//   Attempt to create DateTimeOffset value from 5/1/2008 8:30:00 AM failed.

// Instantiate a DateTimeOffset value with an arbitrary time zone.
string timeZoneName = "Central Standard Time";
TimeSpan offset = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName).
                         GetUtcOffset(sourceDate);
targetTime = new DateTimeOffset(sourceDate, offset);
Console.WriteLine(targetTime);
// Displays 5/1/2008 8:30:00 AM -05:00
Dim sourceDate As Date = #5/1/2008 8:30 AM#
Dim targetTime As DateTimeOffset

' Instantiate a DateTimeOffset value from a UTC time with a zero offset.
Dim utcTime As Date = Date.SpecifyKind(sourceDate, DateTimeKind.Utc)
targetTime = New DateTimeOffset(utcTime, TimeSpan.Zero)
Console.WriteLine(targetTime)
' Displays 5/1/2008 8:30:00 AM +00:00
' Because the Kind property is DateTimeKind.Utc,  
' the call to the constructor succeeds.

' Instantiate a DateTimeOffset value from a UTC time with a non-zero offset.
Try
    targetTime = New DateTimeOffset(utcTime, New TimeSpan(-2, 0, 0))
    Console.WriteLine(targetTime)
Catch e As ArgumentException
    Console.WriteLine("Attempt to create DateTimeOffset value from {0} failed.", _
                       utcTime)
End Try
' Throws exception and displays the following to the console:
'   Attempt to create DateTimeOffset value from 5/1/2008 8:30:00 AM failed.

' Instantiate a DateTimeOffset value from a local time with 
' the offset of the local time zone.
Dim localTime As Date = Date.SpecifyKind(sourceDate, DateTimeKind.Local)
targetTime = New DateTimeOffset(localTime, _
                                TimeZoneInfo.Local.GetUtcOffset(localTime))
Console.WriteLine(targetTime)
' Because the Kind property is DateTimeKind.Local and the offset matches
' that of the local time zone, the call to the constructor succeeds.

' Instantiate a DateTimeOffset value from a local time with a zero offset.
Try
    targetTime = New DateTimeOffset(localTime, TimeSpan.Zero)
    Console.WriteLine(targetTime)
Catch e As ArgumentException
    Console.WriteLine("Attempt to create DateTimeOffset value from {0} failed.", _
                       localTime)
End Try
' Throws exception and displays the following to the console:
'   Attempt to create DateTimeOffset value from 5/1/2008 8:30:00 AM failed.

' Instantiate a DateTimeOffset value with an arbitrary time zone.
Dim timeZoneName As String = "Central Standard Time"
Dim offset As TimeSpan = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName). _
                         GetUtcOffset(sourceDate)
targetTime = New DateTimeOffset(sourceDate, offset)
Console.WriteLine(targetTime)
' Displays 5/1/2008 8:30:00 AM -05:00

隐式类型转换

DateTimeOffset 类型支持一个 隐式 类型转换:从 DateTime 值转换为 DateTimeOffset 值。 隐式类型转换是指将一种类型转换为另一种类型,这个过程中无需在 C# 中使用显式强制转换或在 Visual Basic 中使用转换操作,并且不会丢失信息。) 它使如下所示的代码成为可能。

DateTimeOffset targetTime;

// The Kind property of sourceDate is DateTimeKind.Unspecified
DateTime sourceDate = new DateTime(2008, 5, 1, 8, 30, 0);
targetTime = sourceDate;
Console.WriteLine(targetTime);
// Displays 5/1/2008 8:30:00 AM -07:00

// define a UTC time (Kind property is DateTimeKind.Utc)
DateTime utcTime = DateTime.SpecifyKind(sourceDate, DateTimeKind.Utc);
targetTime = utcTime;
Console.WriteLine(targetTime);
// Displays 5/1/2008 8:30:00 AM +00:00

// Define a local time (Kind property is DateTimeKind.Local)
DateTime localTime = DateTime.SpecifyKind(sourceDate, DateTimeKind.Local);
targetTime = localTime;
Console.WriteLine(targetTime);
// Displays 5/1/2008 8:30:00 AM -07:00
Dim targetTime As DateTimeOffset

' The Kind property of sourceDate is DateTimeKind.Unspecified
Dim sourceDate As Date = #5/1/2008 8:30 AM#
targetTime = sourceDate
Console.WriteLine(targetTime)
' Displays 5/1/2008 8:30:00 AM -07:00

' define a UTC time (Kind property is DateTimeKind.Utc)
Dim utcTime As Date = Date.SpecifyKind(sourceDate, DateTimeKind.Utc)
targetTime = utcTime
Console.WriteLine(targetTime)
' Displays 5/1/2008 8:30:00 AM +00:00

' Define a local time (Kind property is DateTimeKind.Local)
Dim localTime As Date = Date.SpecifyKind(sourceDate, DateTimeKind.Local)
targetTime = localTime
Console.WriteLine(targetTime)
' Displays 5/1/2008 8:30:00 AM -07:00

生成的 DateTimeOffset 值的偏移量取决于 DateTime.Kind 属性值。 如果其值为 DateTimeKind.Utc,则偏移量设置为等于 TimeSpan.Zero。 如果其值为DateTimeKind.LocalDateTimeKind.Unspecified,偏移量将设置为等于本地时区的偏移量。

分析日期和时间的字符串表示形式

DateTimeOffset 类型支持四种方法,可用于将日期和时间的字符串表示形式转换为 DateTimeOffset 值:

  • Parse,尝试将日期和时间 DateTimeOffset 的字符串表示形式转换为值,并在转换失败时引发异常。

  • TryParse,尝试将日期和时间 DateTimeOffset 的字符串表示形式转换为值,并在转换失败时返回 false

  • ParseExact,它尝试将指定格式的日期和时间的字符串表示形式转换为 DateTimeOffset 值。 如果转换失败,该方法将引发异常。

  • TryParseExact,它尝试将指定格式的日期和时间的字符串表示形式转换为 DateTimeOffset 值。 如果转换失败,此方法将 false 返回。

下面的示例演示如何调用这四个字符串转换方法中的每一个来实例化值 DateTimeOffset

string timeString;
DateTimeOffset targetTime;

timeString = "05/01/2008 8:30 AM +01:00";
try
{
   targetTime = DateTimeOffset.Parse(timeString);
   Console.WriteLine(targetTime);
}
catch (FormatException)
{
   Console.WriteLine($"Unable to parse {timeString}.");
}

timeString = "05/01/2008 8:30 AM";
if (DateTimeOffset.TryParse(timeString, out targetTime))
   Console.WriteLine(targetTime);
else
   Console.WriteLine($"Unable to parse {timeString}.");

timeString = "Thursday, 01 May 2008 08:30";
try
{
   targetTime = DateTimeOffset.ParseExact(timeString, "f",
                CultureInfo.InvariantCulture);
   Console.WriteLine(targetTime);
}
catch (FormatException)
{
   Console.WriteLine($"Unable to parse {timeString}.");
}

timeString = "Thursday, 01 May 2008 08:30 +02:00";
string formatString;
formatString = CultureInfo.InvariantCulture.DateTimeFormat.LongDatePattern +
                " " +
                CultureInfo.InvariantCulture.DateTimeFormat.ShortTimePattern +
                " zzz";
if (DateTimeOffset.TryParseExact(timeString,
                                formatString,
                                CultureInfo.InvariantCulture,
                                DateTimeStyles.AllowLeadingWhite,
                                out targetTime))
   Console.WriteLine(targetTime);
else
   Console.WriteLine($"Unable to parse {timeString}.");
// The example displays the following output to the console:
//    5/1/2008 8:30:00 AM +01:00
//    5/1/2008 8:30:00 AM -07:00
//    5/1/2008 8:30:00 AM -07:00
//    5/1/2008 8:30:00 AM +02:00
Dim timeString As String
Dim targetTime As DateTimeOffset

timeString = "05/01/2008 8:30 AM +01:00"
Try
    targetTime = DateTimeOffset.Parse(timeString)
    Console.WriteLine(targetTime)
Catch e As FormatException
    Console.WriteLine("Unable to parse {0}.", timeString)
End Try

timeString = "05/01/2008 8:30 AM"
If DateTimeOffset.TryParse(timeString, targetTime) Then
    Console.WriteLine(targetTime)
Else
    Console.WriteLine("Unable to parse {0}.", timeString)
End If

timeString = "Thursday, 01 May 2008 08:30"
Try
    targetTime = DateTimeOffset.ParseExact(timeString, "f", _
                 CultureInfo.InvariantCulture)
    Console.WriteLine(targetTime)
Catch e As FormatException
    Console.WriteLine("Unable to parse {0}.", timeString)
End Try

timeString = "Thursday, 01 May 2008 08:30 +02:00"
Dim formatString As String
formatString = CultureInfo.InvariantCulture.DateTimeFormat.LongDatePattern & _
                " " & _
                CultureInfo.InvariantCulture.DateTimeFormat.ShortTimePattern & _
                " zzz"
If DateTimeOffset.TryParseExact(timeString, _
                                formatString, _
                                CultureInfo.InvariantCulture, _
                                DateTimeStyles.AllowLeadingWhite, _
                                targetTime) Then
    Console.WriteLine(targetTime)
Else
    Console.WriteLine("Unable to parse {0}.", timeString)
End If
' The example displays the following output to the console:
'    5/1/2008 8:30:00 AM +01:00
'    5/1/2008 8:30:00 AM -07:00
'    5/1/2008 8:30:00 AM -07:00
'    5/1/2008 8:30:00 AM +02:00

另见