共用方式為


HOW TO:讓使用者解決模稜兩可的時間

更新:2007 年 11 月

模稜兩可的時間就是可以對應至一個以上 Coordinated Universal Time (UTC) 的時間。這會發生在時間及時調回時,例如從某個時區的日光節約時間轉換回標準時間時。處理模稜兩可的時間時,您可以執行下列其中一項步驟:

  • 如果模稜兩可的時間是使用者所輸入的資料項目,您可以將這個情形留給使用者解決。

  • 假設時間如何對應至 UTC。例如,您可以假設模稜兩可的時間永遠都是以時區的標準時間表示。

本主題說明如何讓使用者解決模稜兩可的時間。

讓使用者解決模稜兩可的時間

  1. 取得使用者輸入的日期與時間。

  2. 呼叫 IsAmbiguousTime 方法以判斷時間是否模稜兩可。

  3. 如果時間模稜兩可,請呼叫 GetAmbiguousTimeOffsets 方法,以擷取 TimeSpan 物件的陣列。陣列中的每一個項目內含模稜兩可的時間可對應的 UTC 位移。

  4. 讓使用者選擇想要的位移。

  5. 將當地時間減去使用者選擇的位移,以獲得 UTC 日期與時間。

  6. 呼叫 static (在 Visual Basic .NET 中為 Shared) SpecifyKind 方法,將 UTC 日期與時間值的 Kind 屬性設定為 DateTimeKind.Utc

範例

下列範例會提示使用者輸入日期與時間,如果時間模稜兩可,會讓使用者選擇模稜兩可的時間對應至的 UTC 時間。

Private Sub GetUserDateInput()
   ' Get date and time from user
   Dim inputDate As Date = GetUserDateTime()
   Dim utcDate As Date

   ' Exit if date has no significant value
   If inputDate = Date.MinValue Then Exit Sub

   If TimeZoneInfo.Local.IsAmbiguousTime(inputDate) Then
      Console.WriteLine("The date you've entered is ambiguous.")
      Console.WriteLine("Please select the correct offset from Universal Coordinated Time:")
      Dim offsets() As TimeSpan = TimeZoneInfo.Local.GetAmbiguousTimeOffsets(inputDate)
      For ctr As Integer = 0 to offsets.Length - 1
         Dim zoneDescription As String
         If offsets(ctr).Equals(TimeZoneInfo.Local.BaseUtcOffset) Then 
            zoneDescription = TimeZoneInfo.Local.StandardName
         Else
            zoneDescription = TimeZoneInfo.Local.DaylightName
         End If
         Console.WriteLine("{0}.) {1} hours, {2} minutes ({3})", _
                           ctr, offsets(ctr).Hours, offsets(ctr).Minutes, zoneDescription)
      Next         
      Console.Write("> ")
      Dim selection As Integer = CInt(Console.ReadLine())

      ' Convert local time to UTC, and set Kind property to DateTimeKind.Utc
      utcDate = Date.SpecifyKind(inputDate - offsets(selection), DateTimeKind.Utc)

      Console.WriteLine("{0} local time corresponds to {1} {2}.", inputDate, utcDate, utcDate.Kind.ToString())
   Else
      utcDate = inputDate.ToUniversalTime()
      Console.WriteLine("{0} local time corresponds to {1} {2}.", inputDate, utcDate, utcDate.Kind.ToString())    
   End If
End Sub

Private Function GetUserDateTime() As Date
   Dim exitFlag As Boolean = False            ' flag to exit loop if date is valid
   Dim dateString As String 
   Dim inputDate As Date = Date.MinValue

   Console.Write("Enter a local date and time: ")
   Do While Not exitFlag
      dateString = Console.ReadLine()
      If dateString.ToUpper = "E" Then exitFlag = True
      If Date.TryParse(dateString, inputDate) Then
         exitFlag = true
      Else   
         Console.Write("Enter a valid date and time, or enter 'e' to exit: ")
      End If
   Loop

   Return inputDate        
End Function
private void GetUserDateInput()
{
   // Get date and time from user
   DateTime inputDate = GetUserDateTime();
   DateTime utcDate;

   // Exit if date has no significant value
   if (inputDate == DateTime.MinValue) return;

   if (TimeZoneInfo.Local.IsAmbiguousTime(inputDate))
   {
      Console.WriteLine("The date you've entered is ambiguous.");
      Console.WriteLine("Please select the correct offset from Universal Coordinated Time:");
      TimeSpan[] offsets = TimeZoneInfo.Local.GetAmbiguousTimeOffsets(inputDate);
      for (int ctr = 0; ctr < offsets.Length; ctr++)
      {
         Console.WriteLine("{0}.) {1} hours, {2} minutes", ctr, offsets[ctr].Hours, offsets[ctr].Minutes);
      }
      Console.Write("> ");
      int selection = Convert.ToInt32(Console.ReadLine());

      // Convert local time to UTC, and set Kind property to DateTimeKind.Utc
      utcDate = DateTime.SpecifyKind(inputDate - offsets[selection], DateTimeKind.Utc);

      Console.WriteLine("{0} local time corresponds to {1} {2}.", inputDate, utcDate, utcDate.Kind.ToString());
   }
   else
   {
      utcDate = inputDate.ToUniversalTime();
      Console.WriteLine("{0} local time corresponds to {1} {2}.", inputDate, utcDate, utcDate.Kind.ToString());    
   }
}

private DateTime GetUserDateTime() 
{
   bool exitFlag = false;             // flag to exit loop if date is valid
   string dateString;  
   DateTime inputDate = DateTime.MinValue;

   Console.Write("Enter a local date and time: ");
   while (! exitFlag)
   {
      dateString = Console.ReadLine();
      if (dateString.ToUpper() == "E")
         exitFlag = true;

      if (DateTime.TryParse(dateString, out inputDate))
         exitFlag = true;
      else
         Console.Write("Enter a valid date and time, or enter 'e' to exit: ");
   }

   return inputDate;        
}

範例程式碼的核心使用 TimeSpan 物件的陣列,指示模稜兩可的時間可能的 UTC 位移。但是,這些位移對使用者來說可能沒有意義。為了釐清位移的意義,程式碼中也註記了位移代表的是當地時區的標準時間,或日光節約時間。程式碼會比較位移和 BaseUtcOffset 屬性的值,以判斷哪個時間是標準時間,哪個時間是日光節約時間。這個屬性指示 UTC 及時區的標準時間之間的時差。

在本範例中,當地時區的所有參考都是透過 TimeZoneInfo.Local 屬性所建立的,當地時區並沒有被指派給物件變數。建議採取這個方法,因為呼叫 TimeZoneInfo.ClearCachedData 方法會使被指派當地時區的任何物件失效。

編譯程式碼

這個範例需要:

  • 將 System.Core.dll 的參考加入至專案中。

  • 以 using 陳述式 (C# 程式碼中的必要項) 匯入 System 命名空間。

請參閱

工作

HOW TO:解決模稜兩可的時間

其他資源

時間和時區