この記事の英語版を表示するには、[英語] のチェック ボックスをオンにしてください。また、テキストにマウス ポインターを合わせると、ポップアップ ウィンドウに英語のテキストを表示することもできます。
翻訳
英語

方法 : ユーザーがあいまいな時刻を解決できるようにする

 

あいまいな時刻とは、複数の世界協定時刻 (UTC: Coordinated Universal Time) に対応する時刻です。 このようなことは、あるタイム ゾーンで夏時間から標準時間に移行する際など、クロック時刻を元に戻すときに発生します。 あいまいな時刻は、次のいずれかの方法で対処できます。

  • あいまいな時刻がユーザーによって入力されたデータの項目である場合は、あいまいさの解決をユーザーに任せることができます。

  • UTC に対する時刻の対応方法を想定します。 たとえば、あいまいな時刻は常にタイム ゾーンの標準時刻を表す、などと想定できます。

このトピックでは、あいまいな時刻をユーザーに解決させる方法について説明します。

あいまいな時刻をユーザーに解決させるには

  1. ユーザーが入力した日付と時刻を取得します。

  2. IsAmbiguousTime メソッドを呼び出して、時刻があいまいかどうかを判定します。

  3. 時刻があいまいな場合は、GetAmbiguousTimeOffsets メソッドを呼び出して、TimeSpan オブジェクトの配列を取得します。 配列の各要素には、あいまいな時刻に対応する可能性のある UTC オフセットが格納されています。

  4. 適切なオフセットを選択するようにユーザーに促します。

  5. ユーザーが選択したオフセットを現地時刻から減算して、UTC の日付と時刻を取得します。

  6. static (Visual Basic .NET では Shared) SpecifyKind メソッドを呼び出して、UTC の日時の値の Kind プロパティに DateTimeKind.Utc を設定します。

使用例

次の例では、日付と時刻の入力をユーザーに要求し、入力された値があいまいな場合は、あいまいな時刻に対応する UTC 時刻をユーザーが選択できるようにします。

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 への参照をプロジェクトに追加する。

  • System 名前空間を using ステートメントでインポートする (C# のコードで必要)。

表示: