DateTimeFormatInfo クラス

この記事は、この API のリファレンス ドキュメントの補足説明です。

DateTimeFormatInfo クラスのプロパティには、次のような日付と時刻の値を書式設定または解析するためのカルチャ固有の情報が含まれています。

  • 日付値の書式設定に使用されるパターン。
  • 時刻値の書式設定に使用されるパターン。
  • 曜日の名前。
  • 月の名前。
  • 時間値で使用される A.M. と P.M. の指定子。
  • 日付を表すカレンダー。

DateTimeFormatInfo オブジェクトのインスタンスを作成する

DateTimeFormatInfo オブジェクトは、インバリアント カルチャ、特定のカルチャ、ニュートラル カルチャ、または現在のカルチャの書式設定規則を表すことができます。 このセクションでは、各種類の DateTimeFormatInfo オブジェクトのインスタンスを作成する方法について説明します。

インバリアント カルチャの DateTimeFormatInfo オブジェクトのインスタンスを作成する

インバリアント カルチャは、カルチャに依存しないカルチャを表します。 これは英語をベースとしますが、英語を話す特定の国/地域はベースとしません。 特定のカルチャのデータは動的であり、新しいカルチャに関する規則やユーザー設定を反映するように変化する可能性がありますが、インバリアント カルチャのデータは変化しません。 インバリアント カルチャの書式設定規則を表す DateTimeFormatInfo オブジェクトは、以下の方法でインスタンスを作成できます。

次の例では、これらの各メソッドを使用して、インバリアント カルチャを表す DateTimeFormatInfo オブジェクトのインスタンスを作成します。 次に、オブジェクトが読み取り専用かどうかを示します。

System.Globalization.DateTimeFormatInfo dtfi;

dtfi = System.Globalization.DateTimeFormatInfo.InvariantInfo;
Console.WriteLine(dtfi.IsReadOnly);

dtfi = new System.Globalization.DateTimeFormatInfo();
Console.WriteLine(dtfi.IsReadOnly);

dtfi = System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat;
Console.WriteLine(dtfi.IsReadOnly);
// The example displays the following output:
//       True
//       False
//       True

特定のカルチャの DateTimeFormatInfo オブジェクトのインスタンスを作成する

特定のカルチャは、特定の国/地域で話される言語を表します。 たとえば、en-US は米国で話される英語を表す特定のカルチャであり、en-CA はカナダで話される英語を表す特定のカルチャです。 特定のカルチャの書式設定規則を表す DateTimeFormatInfo オブジェクトは、以下の方法でインスタンスを作成できます。

次の例では、これらの各方法で DateTimeFormatInfo オブジェクトのインスタンスを作成し、結果のオブジェクトが読み取り専用かどうかを示します。

System.Globalization.CultureInfo ci = null;
System.Globalization.DateTimeFormatInfo dtfi = null;

// Instantiate a culture using CreateSpecificCulture.
ci = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");
dtfi = ci.DateTimeFormat;
Console.WriteLine("{0} from CreateSpecificCulture: {1}", ci.Name, dtfi.IsReadOnly);

// Instantiate a culture using the CultureInfo constructor.
ci = new System.Globalization.CultureInfo("en-CA");
dtfi = ci.DateTimeFormat;
Console.WriteLine("{0} from CultureInfo constructor: {1}", ci.Name, dtfi.IsReadOnly);

// Retrieve a culture by calling the GetCultureInfo method.
ci = System.Globalization.CultureInfo.GetCultureInfo("en-AU");
dtfi = ci.DateTimeFormat;
Console.WriteLine("{0} from GetCultureInfo: {1}", ci.Name, dtfi.IsReadOnly);

// Instantiate a DateTimeFormatInfo object by calling DateTimeFormatInfo.GetInstance.
ci = System.Globalization.CultureInfo.CreateSpecificCulture("en-GB");
dtfi = System.Globalization.DateTimeFormatInfo.GetInstance(ci);
Console.WriteLine("{0} from GetInstance: {1}", ci.Name, dtfi.IsReadOnly);

// The example displays the following output:
//      en-US from CreateSpecificCulture: False
//      en-CA from CultureInfo constructor: False
//      en-AU from GetCultureInfo: True
//      en-GB from GetInstance: False

ニュートラル カルチャの DateTimeFormatInfo オブジェクトのインスタンスを作成する

ニュートラル カルチャは、国/地域に依存しないカルチャまたは言語を表します。通常、これは 1 つ以上の特定のカルチャの親です。 たとえば、Fr はフランス語のニュートラル カルチャであり、fr-FR カルチャの親です。 ニュートラル カルチャの書式設定規則を表す DateTimeFormatInfo オブジェクトは、特定のカルチャの書式設定規則を表す DateTimeFormatInfo オブジェクトを作成するのと同じ方法でインスタンスを作成できます。 さらに、特定のカルチャの CultureInfo.Parent プロパティからニュートラル カルチャを取得し、その CultureInfo.DateTimeFormat プロパティによって返される DateTimeFormatInfo オブジェクトを取得することで、ニュートラル カルチャの DateTimeFormatInfo オブジェクトを取得できます。 親カルチャがインバリアント カルチャを表さない限り、返される DateTimeFormatInfo オブジェクトは読み取り/書き込みになります。 次の例は、ニュートラル カルチャを表す DateTimeFormatInfo オブジェクトのインスタンスを作成するこれらの方法を示しています。

System.Globalization.CultureInfo specific, neutral;
System.Globalization.DateTimeFormatInfo dtfi;

// Instantiate a culture by creating a specific culture and using its Parent property.
specific = System.Globalization.CultureInfo.GetCultureInfo("fr-FR");
neutral = specific.Parent;
dtfi = neutral.DateTimeFormat;
Console.WriteLine("{0} from Parent property: {1}", neutral.Name, dtfi.IsReadOnly);

dtfi = System.Globalization.CultureInfo.GetCultureInfo("fr-FR").Parent.DateTimeFormat;
Console.WriteLine("{0} from Parent property: {1}", neutral.Name, dtfi.IsReadOnly);

// Instantiate a neutral culture using the CultureInfo constructor.
neutral = new System.Globalization.CultureInfo("fr");
dtfi = neutral.DateTimeFormat;
Console.WriteLine("{0} from CultureInfo constructor: {1}", neutral.Name, dtfi.IsReadOnly);

// Instantiate a culture using CreateSpecificCulture.
neutral = System.Globalization.CultureInfo.CreateSpecificCulture("fr");
dtfi = neutral.DateTimeFormat;
Console.WriteLine("{0} from CreateSpecificCulture: {1}", neutral.Name, dtfi.IsReadOnly);

// Retrieve a culture by calling the GetCultureInfo method.
neutral = System.Globalization.CultureInfo.GetCultureInfo("fr");
dtfi = neutral.DateTimeFormat;
Console.WriteLine("{0} from GetCultureInfo: {1}", neutral.Name, dtfi.IsReadOnly);

// Instantiate a DateTimeFormatInfo object by calling GetInstance.
neutral = System.Globalization.CultureInfo.CreateSpecificCulture("fr");
dtfi = System.Globalization.DateTimeFormatInfo.GetInstance(neutral);
Console.WriteLine("{0} from GetInstance: {1}", neutral.Name, dtfi.IsReadOnly);

// The example displays the following output:
//       fr from Parent property: False
//       fr from Parent property: False
//       fr from CultureInfo constructor: False
//       fr-FR from CreateSpecificCulture: False
//       fr from GetCultureInfo: True
//       fr-FR from GetInstance: False

ただし、ニュートラル カルチャは特定の国/地域に依存しないため、ニュートラル カルチャにはカルチャ固有の書式設定情報がありません。 .NET は、DateTimeFormatInfo オブジェクトに汎用値を設定するのではなく、ニュートラル カルチャの子である特定のカルチャの書式設定規則を反映する DateTimeFormatInfo オブジェクトを返します。 たとえば、ニュートラルな en カルチャの DateTimeFormatInfo オブジェクトは en-US カルチャの書式設定規則を反映し、fr カルチャの DateTimeFormatInfo オブジェクトは fr-FR カルチャの書式設定規則を反映します。

次のようなコードを使用して、ニュートラル カルチャが表す特定のカルチャの書式設定規則を判別できます。 この例では、リフレクションを使用して、ニュートラル カルチャの DateTimeFormatInfo プロパティと特定の子カルチャのプロパティを比較します。 2 つのカレンダーが同じカレンダーの種類である場合は、同等と見なされ、グレゴリオ暦の場合は、GregorianCalendar.CalendarType プロパティの値が同じであれば同等と見なされます。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;

public class InstantiateEx6
{
    public static void Main()
    {
        // Get all the neutral cultures
        List<String> names = new List<String>();
        Array.ForEach(CultureInfo.GetCultures(CultureTypes.NeutralCultures),
                      culture => names.Add(culture.Name));
        names.Sort();
        foreach (var name in names)
        {
            // Ignore the invariant culture.
            if (name == "") continue;

            ListSimilarChildCultures(name);
        }
    }

    private static void ListSimilarChildCultures(String name)
    {
        // Create the neutral DateTimeFormatInfo object.
        DateTimeFormatInfo dtfi = CultureInfo.GetCultureInfo(name).DateTimeFormat;
        // Retrieve all specific cultures of the neutral culture.
        CultureInfo[] cultures = Array.FindAll(CultureInfo.GetCultures(CultureTypes.SpecificCultures),
                                 culture => culture.Name.StartsWith(name + "-", StringComparison.OrdinalIgnoreCase));
        // Create an array of DateTimeFormatInfo properties
        PropertyInfo[] properties = typeof(DateTimeFormatInfo).GetProperties(BindingFlags.Instance | BindingFlags.Public);
        bool hasOneMatch = false;

        foreach (var ci in cultures)
        {
            bool match = true;
            // Get the DateTimeFormatInfo for a specific culture.
            DateTimeFormatInfo specificDtfi = ci.DateTimeFormat;
            // Compare the property values of the two.
            foreach (var prop in properties)
            {
                // We're not interested in the value of IsReadOnly.
                if (prop.Name == "IsReadOnly") continue;

                // For arrays, iterate the individual elements to see if they are the same.
                if (prop.PropertyType.IsArray)
                {
                    IList nList = (IList)prop.GetValue(dtfi, null);
                    IList sList = (IList)prop.GetValue(specificDtfi, null);
                    if (nList.Count != sList.Count)
                    {
                        match = false;
                        Console.WriteLine("   Different n in {2} array for {0} and {1}", name, ci.Name, prop.Name);
                        break;
                    }

                    for (int ctr = 0; ctr < nList.Count; ctr++)
                    {
                        if (!nList[ctr].Equals(sList[ctr]))
                        {
                            match = false;
                            Console.WriteLine("   {0} value different for {1} and {2}", prop.Name, name, ci.Name);
                            break;
                        }
                    }

                    if (!match) break;
                }
                // Get non-array values.
                else
                {
                    Object specificValue = prop.GetValue(specificDtfi);
                    Object neutralValue = prop.GetValue(dtfi);

                    // Handle comparison of Calendar objects.
                    if (prop.Name == "Calendar")
                    {
                        // The cultures have a different calendar type.
                        if (specificValue.ToString() != neutralValue.ToString())
                        {
                            Console.WriteLine("   Different calendar types for {0} and {1}", name, ci.Name);
                            match = false;
                            break;
                        }

                        if (specificValue is GregorianCalendar)
                        {
                            if (((GregorianCalendar)specificValue).CalendarType != ((GregorianCalendar)neutralValue).CalendarType)
                            {
                                Console.WriteLine("   Different Gregorian calendar types for {0} and {1}", name, ci.Name);
                                match = false;
                                break;
                            }
                        }
                    }
                    else if (!specificValue.Equals(neutralValue))
                    {
                        match = false;
                        Console.WriteLine("   Different {0} values for {1} and {2}", prop.Name, name, ci.Name);
                        break;
                    }
                }
            }
            if (match)
            {
                Console.WriteLine("DateTimeFormatInfo object for '{0}' matches '{1}'",
                                  name, ci.Name);
                hasOneMatch = true;
            }
        }
        if (!hasOneMatch)
            Console.WriteLine("DateTimeFormatInfo object for '{0}' --> No Match", name);

        Console.WriteLine();
    }
}

現在のカルチャの DateTimeFormatInfo オブジェクトのインスタンスを作成する

現在のカルチャの書式設定規則を表す DateTimeFormatInfo オブジェクトは、以下の方法でインスタンスを作成できます。

次の例では、これらの各メソッドを使用して、現在のカルチャの書式設定規則を表す DateTimeFormatInfo オブジェクトをインスタンス化します。 次に、オブジェクトが読み取り専用かどうかを示します。

DateTimeFormatInfo dtfi;

dtfi = DateTimeFormatInfo.CurrentInfo;
Console.WriteLine(dtfi.IsReadOnly);

dtfi = CultureInfo.CurrentCulture.DateTimeFormat;
Console.WriteLine(dtfi.IsReadOnly);

dtfi = DateTimeFormatInfo.GetInstance(CultureInfo.CurrentCulture);
Console.WriteLine(dtfi.IsReadOnly);
// The example displays the following output:
//     True
//     True
//     True

以下のいずれかの方法で、現在のカルチャの規則を表す書き込み可能な DateTimeFormatInfo オブジェクトを作成できます。

次の例は、読み取り/書き込み DateTimeFormatInfo オブジェクトのインスタンスを作成する各方法を示し、その IsReadOnly プロパティの値を表示します。

using System;
using System.Globalization;

public class InstantiateEx1
{
    public static void Main()
    {
        DateTimeFormatInfo current1 = DateTimeFormatInfo.CurrentInfo;
        current1 = (DateTimeFormatInfo)current1.Clone();
        Console.WriteLine(current1.IsReadOnly);

        CultureInfo culture2 = CultureInfo.CreateSpecificCulture(CultureInfo.CurrentCulture.Name);
        DateTimeFormatInfo current2 = culture2.DateTimeFormat;
        Console.WriteLine(current2.IsReadOnly);
    }
}
// The example displays the following output:
//       False
//       False

Windows では、ユーザーは、コントロール パネルの地域と言語アプリケーションを使用して、書式設定および解析操作で使用される DateTimeFormatInfo プロパティ値の一部をオーバーライドできます。 たとえば、カルチャが英語 (米国) のユーザーは、既定の 12 時間時計 (h:mm:ss tt 形式) ではなく、24 時間制 (HH:mm:ss 形式) を使用して長い時間値を表示することを選択できます。 先ほど説明した方法で取得した DateTimeFormatInfo オブジェクトは、これらのユーザーのオーバーライドのすべてを反映します。 これが望ましくない場合は、CultureInfo.CultureInfo(String, Boolean) コンストラクターを呼び出して useUserOverride 引数に false 値を与えることで、ユーザーのオーバーライドを反映しない (かつ読み取り専用ではなく読み取り/書き込み可能な) NumberFormatInfo オブジェクトを作成できます。 次の例は、現在のカルチャが英語 (米国) で、長い時間パターンが既定の h:mm:ss tt から HH:mm:ss に変更されているシステムでの場合を示しています。

using System;
using System.Globalization;

public class InstantiateEx3
{
    public static void Main()
    {
        CultureInfo culture;
        DateTimeFormatInfo dtfi;

        culture = CultureInfo.CurrentCulture;
        dtfi = culture.DateTimeFormat;
        Console.WriteLine("Culture Name:      {0}", culture.Name);
        Console.WriteLine("User Overrides:    {0}", culture.UseUserOverride);
        Console.WriteLine("Long Time Pattern: {0}\n", culture.DateTimeFormat.LongTimePattern);

        culture = new CultureInfo(CultureInfo.CurrentCulture.Name, false);
        Console.WriteLine("Culture Name:      {0}", culture.Name);
        Console.WriteLine("User Overrides:    {0}", culture.UseUserOverride);
        Console.WriteLine("Long Time Pattern: {0}\n", culture.DateTimeFormat.LongTimePattern);
    }
}
// The example displays the following output:
//       Culture Name:      en-US
//       User Overrides:    True
//       Long Time Pattern: HH:mm:ss
//
//       Culture Name:      en-US
//       User Overrides:    False
//       Long Time Pattern: h:mm:ss tt

DateTimeFormatInfo と動的データ

DateTimeFormatInfo クラスによって提供される日付と時刻の値を書式設定するためのカルチャ固有のデータは、CultureInfo クラスによって提供されるカルチャ データと同様に動的です。 特定の CultureInfo オブジェクトに関連付けられている DateTimeFormatInfo オブジェクトの値の安定性に関してはどのような仮定も行うべきではありません。 安定しているのは、インバリアント カルチャとそれに関連付けられている DateTimeFormatInfo オブジェクトによって提供されるデータだけです。 その他のデータは、アプリケーション セッション間や、アプリケーションの実行中に変更される可能性があります。 変更の主な原因は 4 つあります。

  • システムの更新プログラム。 優先カレンダーや慣例の日付と時刻の形式などのカルチャの設定は、時間の経過と同時に変化します。 この場合、Windows Update は、特定のカルチャの DateTimeFormatInfo プロパティ値に変更内容を含めます。

  • 置換カルチャ。 CultureAndRegionInfoBuilder クラスは、既存カルチャのデータを置き換えるために使用されます。

  • プロパティ値に対する連鎖的変更。 いくつかのカルチャ関連プロパティは実行時に変化する可能性があり、その結果、DateTimeFormatInfo データが変化します。 たとえば、現在のカルチャは、プログラム的に、またはユーザー アクション通じて変更される可能性があります。 この場合、CurrentInfo プロパティによって返される DateTimeFormatInfo オブジェクトは、現在のカルチャに関連付けられているオブジェクトに変化します。 同様に、カルチャのカレンダーは変更される可能性があり、その結果、多数の DateTimeFormatInfo のプロパティ値が変更される可能性があります。

  • ユーザー設定。 アプリケーションのユーザーは、コントロール パネルの地域と言語オプションを通して、現在のシステム カルチャに関連付けられている値の一部をオーバーライドすることを選択する場合があります。 たとえば、ユーザーは別の形式で日付を表示することを選択できます。 CultureInfo.UseUserOverride プロパティが true に設定されていると、ユーザー設定からは DateTimeFormatInfo オブジェクトのプロパティも取得されます。 ユーザー設定が CultureInfo オブジェクトに関連付けられているカルチャと互換性がない場合 (たとえば、選択したカレンダーが OptionalCalendars プロパティに示されているカレンダーのいずれかでない場合)、メソッドの結果とプロパティの値は未定義になります。

データに不整合が生じる可能性を最小限に抑えるために、オブジェクトの作成時に、DateTimeFormatInfo オブジェクトのユーザーがオーバーライドできるすべてのプロパティが初期化されます。 オブジェクトの作成とユーザー オーバーライド プロセスはどちらもアトミックでなく、オブジェクトの作成時に関連する値が変化する場合があるため、不整合が発生する可能性があります。 ただし、この状況は非常にまれです。

ユーザー オーバーライドが、システムのカルチャと同じカルチャを表す DateTimeFormatInfo オブジェクトに反映されるかどうかを制御できます。 次の表は、DateTimeFormatInfo オブジェクトを取得できる方法の一覧と、結果オブジェクトがユーザー オーバーライドを反映するかどうかを示しています。

CultureInfo オブジェクトと DateTimeFormatInfo オブジェクトのソース ユーザー オーバーライドを反映するか
CultureInfo.CurrentCulture.DateTimeFormat プロパティ はい
DateTimeFormatInfo.CurrentInfo プロパティ はい
CultureInfo.CreateSpecificCulture メソッド はい
CultureInfo.GetCultureInfo メソッド いいえ
CultureInfo.CultureInfo(String) コンストラクター はい
CultureInfo.CultureInfo(String, Boolean) コンストラクター useUserOverride パラメーターの値に依存

そうしないだけのやむを得ない理由がない限りは、クライアント アプリケーションで DateTimeFormatInfo オブジェクトを使用してユーザー入力の書式設定と解析を行ったり、データを表示したりする際には、ユーザー オーバーライドを優先する必要があります。 サーバー アプリケーションや無人アプリケーションの場合は、ユーザー オーバーライドを優先するべきではありません。 ただし、文字列形式で日付と時刻のデータを保持するために DateTimeFormatInfo オブジェクトを明示的または暗黙的に使用する場合は、インバリアント カルチャの書式設定規則を反映する DateTimeFormatInfo オブジェクトを使用するか、カルチャに関係なく使用するカスタムの日付と時刻の書式設定文字列を指定する必要があります。

日付と時刻の書式設定

DateTimeFormatInfo オブジェクトは、すべての日付と時刻の書式設定操作で暗黙的または明示的に使用されます。 これには、以下のメソッドの呼び出しが含まれます。

すべての日付と時刻の書式設定操作は、IFormatProvider の実装を使用します。 IFormatProvider インターフェイスには単一メソッドである IFormatProvider.GetFormat(Type) が含まれます。 このコールバック メソッドには、書式設定情報を提供するために必要な型を表す Type オブジェクトが渡されます。 このメソッドは、その型のインスタンスまたは null (その型のインスタンスを返せない場合) のどちらかを返します。 .NET には、日付と時刻を書式設定するための 2 つの IFormatProvider 実装が含まれています。

IFormatProvider の実装が書式設定メソッドに明示的に渡されない場合は、現在のカルチャを表す CultureInfo.CurrentCulture プロパティによって返される CultureInfo オブジェクトが使用されます。

次の例は、書式設定操作における IFormatProvider インターフェイスと DateTimeFormatInfo クラスの間の関係を明らかにします。 これは、書式設定操作によって要求されたオブジェクトの型を表示する GetFormat メソッドを持つカスタム IFormatProvider 実装を定義します。 これが DateTimeFormatInfo オブジェクトを要求している場合、このメソッドは現在のカルチャの DateTimeFormatInfo オブジェクトを提供します。 この例の出力が示すように、Decimal.ToString(IFormatProvider) メソッドは書式設定情報を提供するために DateTimeFormatInfo オブジェクトを必要とする一方、String.Format(IFormatProvider, String, Object[]) メソッドは ICustomFormatter の実装に加え、NumberFormatInfo および DateTimeFormatInfo オブジェクトを必要とします。

using System;
using System.Globalization;

public class CurrentCultureFormatProvider : IFormatProvider
{
    public Object GetFormat(Type formatType)
    {
        Console.WriteLine("Requesting an object of type {0}",
                          formatType.Name);
        if (formatType == typeof(NumberFormatInfo))
            return NumberFormatInfo.CurrentInfo;
        else if (formatType == typeof(DateTimeFormatInfo))
            return DateTimeFormatInfo.CurrentInfo;
        else
            return null;
    }
}

public class FormatProviderEx1
{
    public static void Main()
    {
        DateTime dateValue = new DateTime(2013, 5, 28, 13, 30, 0);
        string value = dateValue.ToString("F", new CurrentCultureFormatProvider());
        Console.WriteLine(value);
        Console.WriteLine();
        string composite = String.Format(new CurrentCultureFormatProvider(),
                                         "Date: {0:d}   Amount: {1:C}   Description: {2}",
                                         dateValue, 1264.03m, "Service Charge");
        Console.WriteLine(composite);
        Console.WriteLine();
    }
}
// The example displays output like the following:
//       Requesting an object of type DateTimeFormatInfo
//       Tuesday, May 28, 2013 1:30:00 PM
//
//       Requesting an object of type ICustomFormatter
//       Requesting an object of type DateTimeFormatInfo
//       Requesting an object of type NumberFormatInfo
//       Date: 5/28/2013   Amount: $1,264.03   Description: Service Charge

書式指定文字列と DateTimeFormatInfo プロパティ

この DateTimeFormatInfo オブジェクトには、日付と時刻の値を使用した書式設定操作で使用される 3 種類のプロパティが含まれています。

"d"、"D"、"f"、"F" などの標準日時書式指定文字列は、特定の DateTimeFormatInfo 書式パターン プロパティに対応するエイリアスです。 カスタム日時書式指定文字列のほとんどは、書式設定操作によって結果ストリームに挿入される文字列または部分文字列に関連しています。 次の表は、標準およびカスタム日時書式指定文字列とそれに関連する DateTimeFormatInfo プロパティを一覧表示したものです。 これらの書式指定子の使用方法の詳細については、「標準日時書式指定文字列」と「カスタム日時書式指定文字列」をご覧ください。 各標準の書式指定文字列は、値がカスタム日時書式指定文字列である DateTimeFormatInfo プロパティに対応します。 このカスタムの書式指定文字列の個々の指定子は、他の DateTimeFormatInfo プロパティに対応します。 この表には、標準書式指定文字列がエイリアスである DateTimeFormatInfo プロパティのみが一覧表示され、それらのエイリアス化されたプロパティに割り当てられたカスタム書式指定文字列によってアクセスできるプロパティは一覧表示されません。 さらに、この表には、DateTimeFormatInfo プロパティに対応するカスタム書式指定子のみが一覧表示されます。

書式指定子 関連するプロパティ
"d" (短い日付: 標準書式指定文字列) ShortDatePattern: 結果文字列の全体的な書式を定義します。
"D" (長い日付: 標準書式指定文字列) LongDatePattern: 結果文字列の全体的な書式を定義します。
"f" (完全な日付/短い時刻: 標準書式指定文字列) LongDatePattern: 結果文字列の日付要素の書式を定義します。

ShortTimePattern: 結果文字列の時刻要素の書式を定義します。
"F" (完全な日付/長い時間;標準書式指定文字列) LongDatePattern: 結果文字列の日付要素の書式を定義します。

LongTimePattern: 結果文字列の時刻要素の書式を定義します。
"g" (一般的な日付/短い時刻: 標準書式指定文字列) ShortDatePattern: 結果文字列の日付要素の書式を定義します。

ShortTimePattern: 結果文字列の時刻要素の書式を定義します。
"G" (一般的な日付/長い時間: 標準書式指定文字列) ShortDatePattern: 結果文字列の日付要素の書式を定義します。

LongTimePattern: 結果文字列の時刻要素の書式を定義します。
"M"、"m" (月/日、標準書式指定文字列) MonthDayPattern: 結果文字列の全体的な書式を定義します。
"O"、"o" (ラウンドトリップ日付/時刻、標準書式指定文字列) なし。
"R"、"r" (RFC1123: 標準書式指定文字列) RFC1123Pattern: RFC 1123 標準に準拠する結果文字列を定義します。 このプロパティは読み取り専用です。
"s" (並べ替え可能な日付/時刻、標準書式指定文字列) SortableDateTimePattern: ISO 8601 標準に準拠する結果文字列を定義します。 このプロパティは読み取り専用です。
"t" (短い時刻: 標準書式指定文字列) ShortTimePattern: 結果文字列の全体的な書式を定義します。
"T" (長い時間: 標準書式指定文字列) LongTimePattern: 結果文字列の全体的な書式を定義します。
"u" (汎用の並べ替え可能な日付/時刻、標準書式指定文字列) UniversalSortableDateTimePattern: 協定世界時の ISO 8601 標準に準拠する結果文字列を定義します。 このプロパティは読み取り専用です。
"U" (ユニバーサル完全な日付/時刻: 標準書式指定文字列) FullDateTimePattern: 結果文字列の全体的な書式を定義します。
"Y"、"y" (年月: 標準書式指定文字列) YearMonthPattern: 結果文字列の全体的な書式を定義します。
"ddd" (カスタム書式指定子) AbbreviatedDayNames: 結果文字列に曜日の省略名を含めます。
"g"、"gg" (カスタム書式指定子) GetEraName メソッドを呼び出して、結果文字列に時代 (年号) の名前を挿入します。
"MMM" (カスタム書式指定子) AbbreviatedMonthNames: 省略された月の名前を結果文字列に含めます。
"MMMM" (カスタム書式指定子) MonthNames または MonthGenitiveNames: 結果文字列に完全な月の名前を含めます。
"t" (カスタム書式指定子) AMDesignator または PMDesignator: AM/PM 指定子の最初の文字を結果文字列に含めます。
"tt" (カスタム書式指定子) AMDesignator または PMDesignator: 結果文字列に完全な AM/PM 指定子を含めます。
":" (カスタム書式指定子) TimeSeparator: 結果文字列に時刻区切り記号を含めます。
"/" (カスタム書式指定子) DateSeparator: 結果文字列に日付区切り記号を含めます。

DateTimeFormatInfo プロパティを変更する

日時書式指定文字列によって生成される結果文字列は、書き込み可能な DateTimeFormatInfo オブジェクトの関連プロパティを変更することで変更できます。 DateTimeFormatInfo オブジェクトが書き込み可能かどうかを判断するには、IsReadOnly プロパティを使用します。 この方法で DateTimeFormatInfo オブジェクトをカスタマイズするには:

  1. 変更したい書式設定規則を持つ DateTimeFormatInfo オブジェクトの読み取り/書き込みコピーを作成します。

  2. 目的の結果文字列を生成するために使用されるプロパティを変更します。 書式設定メソッドがどのように DateTimeFormatInfo プロパティを使用して結果文字列を定義するかについては、前のセクション「書式設定文字列と DateTimeFormatInfo プロパティ」を参照してください。

  3. 書式設定メソッドの呼び出しで、作成したカスタム DateTimeFormatInfo オブジェクトを IFormatProvider 引数として使用します。

結果文字列の形式を変更するには、他に 2 つの方法があります。

  • この CultureAndRegionInfoBuilder クラスを使用して、カスタム カルチャ (一意の名前を持ち、既存のカルチャを補完するカルチャ) または置換カルチャ (特定のカルチャの代わりに使用されるカルチャ) を定義できます。 .NET でサポートされている CultureInfo オブジェクトと同様に、プログラムでこのカルチャを保存してアクセスできます。

  • 結果文字列がカルチャに依存せず、定義済みの形式に従っていない場合は、カスタム日時書式指定文字列を使用できます。 たとえば、日付と時刻のデータを YYYYMMDDHHmmss 形式でシリアル化する場合は、カスタム書式指定文字列を DateTime.ToString(String) メソッドに渡すことで結果文字列を生成し、DateTime.ParseExact メソッドを呼び出して結果文字列を DateTime 値に変換できます。

短い日付パターンを変更する

次の例では、"d" (短い日付) 標準書式指定文字列によって生成される結果文字列の形式を変更します。 en-US または英語 (米国) カルチャの関連付けられている ShortDatePattern プロパティを既定の "M/d/yyyy" から "yyyy'-"MM"-"dd" に変更し、"d" 標準書式指定文字列を使用して、ShortDatePattern プロパティが変更される前と後の両方の日付を表示します。

using System;
using System.Globalization;

public class Example1
{
    public static void Main()
    {
        DateTime dateValue = new DateTime(2013, 8, 18);
        CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
        DateTimeFormatInfo dtfi = enUS.DateTimeFormat;

        Console.WriteLine("Before modifying DateTimeFormatInfo object: ");
        Console.WriteLine("{0}: {1}\n", dtfi.ShortDatePattern,
                                      dateValue.ToString("d", enUS));

        // Modify the short date pattern.
        dtfi.ShortDatePattern = "yyyy-MM-dd";
        Console.WriteLine("After modifying DateTimeFormatInfo object: ");
        Console.WriteLine("{0}: {1}", dtfi.ShortDatePattern,
                                      dateValue.ToString("d", enUS));
    }
}
// The example displays the following output:
//       Before modifying DateTimeFormatInfo object:
//       M/d/yyyy: 8/18/2013
//
//       After modifying DateTimeFormatInfo object:
//       yyyy-MM-dd: 2013-08-18

日付区切り文字を変更する

次の使用例では、fr-FR カルチャの書式規則を表す DateTimeFormatInfo オブジェクトの日付区切り文字を変更します。 この例では、"g" 標準書式指定文字列を使用して、DateSeparator プロパティが変更される前と後の両方の日付を表示します。

using System;
using System.Globalization;

public class Example3
{
    public static void Main()
    {
        DateTime dateValue = new DateTime(2013, 08, 28);
        CultureInfo frFR = CultureInfo.CreateSpecificCulture("fr-FR");
        DateTimeFormatInfo dtfi = frFR.DateTimeFormat;

        Console.WriteLine("Before modifying DateSeparator property: {0}",
                          dateValue.ToString("g", frFR));

        // Modify the date separator.
        dtfi.DateSeparator = "-";
        Console.WriteLine("After modifying the DateSeparator property: {0}",
                          dateValue.ToString("g", frFR));
    }
}
// The example displays the following output:
//       Before modifying DateSeparator property: 28/08/2013 00:00
//       After modifying the DateSeparator property: 28-08-2013 00:00

曜日名の省略形と長い日付パターンを変更する

場合によっては、通常、完全な日と月の名前が月の日付と年の数と共に表示される長い日付パターンが長すぎる可能性があります。 次の例では、en-US カルチャの長い日付パターンを短くして、1 文字または 2 文字の日の名前の省略形の後に日付番号、月名の省略形、および年を返します。 これを行うには、短い曜日名の省略形を AbbreviatedDayNames 配列に割り当て、LongDatePattern プロパティに割り当てられているカスタム書式指定文字列を変更します。 これは、"D" および "f" 標準書式指定文字列によって返される結果文字列に影響します。

using System;
using System.Globalization;

public class Example2
{
    public static void Main()
    {
        DateTime value = new DateTime(2013, 7, 9);
        CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
        DateTimeFormatInfo dtfi = enUS.DateTimeFormat;
        String[] formats = { "D", "F", "f" };

        // Display date before modifying properties.
        foreach (var fmt in formats)
            Console.WriteLine("{0}: {1}", fmt, value.ToString(fmt, dtfi));

        Console.WriteLine();

        // We don't want to change the FullDateTimePattern, so we need to save it.
        String originalFullDateTimePattern = dtfi.FullDateTimePattern;

        // Modify day name abbreviations and long date pattern.
        dtfi.AbbreviatedDayNames = new String[] { "Su", "M", "Tu", "W", "Th", "F", "Sa" };
        dtfi.LongDatePattern = "ddd dd-MMM-yyyy";
        dtfi.FullDateTimePattern = originalFullDateTimePattern;
        foreach (var fmt in formats)
            Console.WriteLine("{0}: {1}", fmt, value.ToString(fmt, dtfi));
    }
}
// The example displays the following output:
//       D: Tuesday, July 9, 2013
//       F: Tuesday, July 9, 2013 12:00:00 AM
//       f: Tuesday, July 9, 2013 12:00 AM
//
//       D: Tu 09-Jul-2013
//       F: Tuesday, July 9, 2013 12:00:00 AM
//       f: Tu 09-Jul-2013 12:00 AM

通常、LongDatePattern プロパティの変更は FullDateTimePattern プロパティにも影響し、"F" 標準書式指定文字列によって返される結果文字列が定義されます。 元の完全な日付と時刻のパターンを保持するために、LongDatePattern プロパティの変更後に FullDateTimePattern プロパティに割り当てられた元のカスタム書式指定文字列を再割り当てします。

12 時間制から 24 時間制に変更する

.NET の多くのカルチャでは、時刻は 12 時間制と AM/PM 指定子を使用して表されます。 次の例では、12 時間制を使用する任意の時刻形式を、24 時間制を使用する形式に置き換える ReplaceWith24HourClock メソッドを定義します。

using System;
using System.Globalization;
using System.Text.RegularExpressions;

public class Example5
{
    public static void Main()
    {
        CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
        DateTimeFormatInfo dtfi = enUS.DateTimeFormat;

        Console.WriteLine("Original Property Values:");
        Console.WriteLine("ShortTimePattern: " + dtfi.ShortTimePattern);
        Console.WriteLine("LongTimePattern: " + dtfi.LongTimePattern);
        Console.WriteLine("FullDateTimePattern: " + dtfi.FullDateTimePattern);
        Console.WriteLine();

        dtfi.LongTimePattern = ReplaceWith24HourClock(dtfi.LongTimePattern);
        dtfi.ShortTimePattern = ReplaceWith24HourClock(dtfi.ShortTimePattern);

        Console.WriteLine("Modififed Property Values:");
        Console.WriteLine("ShortTimePattern: " + dtfi.ShortTimePattern);
        Console.WriteLine("LongTimePattern: " + dtfi.LongTimePattern);
        Console.WriteLine("FullDateTimePattern: " + dtfi.FullDateTimePattern);
    }

    private static string ReplaceWith24HourClock(string fmt)
    {
        string pattern = @"^(?<openAMPM>\s*t+\s*)? " +
                         @"(?(openAMPM) h+(?<nonHours>[^ht]+)$ " +
                         @"| \s*h+(?<nonHours>[^ht]+)\s*t+)";
        return Regex.Replace(fmt, pattern, "HH${nonHours}",
                             RegexOptions.IgnorePatternWhitespace);
    }
}
// The example displays the following output:
//       Original Property Values:
//       ShortTimePattern: h:mm tt
//       LongTimePattern: h:mm:ss tt
//       FullDateTimePattern: dddd, MMMM dd, yyyy h:mm:ss tt
//
//       Modififed Property Values:
//       ShortTimePattern: HH:mm
//       LongTimePattern: HH:mm:ss
//       FullDateTimePattern: dddd, MMMM dd, yyyy HH:mm:ss

この例では、正規表現を使用して書式指定文字列を変更します。 正規表現パターン @"^(?<openAMPM>\s*t+\s*)? (?(openAMPM) h+(?<nonHours>[^ht]+)$ | \s*h+(?<nonHours>[^ht]+)\s*t+) は、次のように定義されます。

パターン 説明
^ 文字列の先頭から照合を開始します。
(?<openAMPM>\s*t+\s*)? 0 個以上の空白文字が 0 個または 1 回出現し、その後に文字 "t" が 1 回以上続き、その後に 0 個以上の空白文字が続きます。 このキャプチャ グループの名前は openAMPM です。
(?(openAMPM) h+(?<nonHours>[^ht]+)$ openAMPM グループが一致する場合は、文字 "h" を 1 回以上一致させ、その後に "h" と "t" のどちらでもない 1 つ以上の文字を一致させます。 一致は文字列の末尾で終了します。 "h" の後にキャプチャされたすべての文字は、nonHours という名前のキャプチャ グループに含まれます。
&#124; \s*h+(?<nonHours>[^ht]+)\s*t+) openAMPM グループが一致しない場合は、文字 "h" を 1 回以上一致し、その後に "h" と "t" のどちらでもない 1 つ以上の文字の後に、0 個以上の空白文字が続きます。 最後に、文字 "t" の 1 つ以上の出現箇所と一致します。 "h" の後、および空白文字と "t" の前にキャプチャされたすべての文字は、nonHours という名前のキャプチャ グループに含まれます。

nonHours キャプチャ グループには、時刻区切り記号と共に、カスタム日時書式指定文字列の分と場合によっては 2 番目のコンポーネントが含まれます。 置換パターン HH${nonHours} は、これらの要素の前に部分文字列 "HH" を付加します。

日付の時代 (年号) を表示および変更する

次の例では、en-US カルチャの書式設定規則を表すオブジェクトの LongDatePattern プロパティに "g" カスタム書式指定子を追加します。 この追加は、次の 3 つの標準書式指定文字列に影響します。

  • "D" (長い日付) 標準書式指定文字列。LongDatePattern プロパティに直接マップされます。

  • "f" (完全な日付/短い時刻) 標準書式指定文字列。この文字列は、LongDatePattern プロパティと ShortTimePattern プロパティによって生成された部分文字列を連結する結果文字列を生成します。

  • "F" (完全な日付/長い時間) 標準書式指定文字列。FullDateTimePattern プロパティに直接マップされます。 このプロパティ値は明示的に設定されていないため、LongDatePattern プロパティと LongTimePattern プロパティを連結して動的に生成されます。

この例では、カレンダーに 1 つの時代 (年号) があるカルチャの年号名を変更する方法も示します。 この場合、en-US カルチャでは、GregorianCalendar オブジェクトで表されるグレゴリオ暦が使用されます。 この GregorianCalendar クラスは、A.D (Anno Domini)という名前の単一の時代 (年号) をサポートしています。 この例では、時代 (年号) の名前を、FullDateTimePattern プロパティに割り当てられた書式指定文字列の "g" カスタム書式指定子をリテラル文字列に置き換えることで C.E. (Common Era) に変更します。 年号名は通常、.NET またはオペレーティング システムによって提供されるカルチャ テーブル内のプライベート データから GetEraName メソッドによって返されるため、リテラル文字列を使用する必要があります。

using System;
using System.Globalization;

public class Example4
{
    public static void Main()
    {
        DateTime dateValue = new DateTime(2013, 5, 18, 13, 30, 0);
        String[] formats = { "D", "f", "F" };

        CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
        DateTimeFormatInfo dtfi = enUS.DateTimeFormat;
        String originalLongDatePattern = dtfi.LongDatePattern;

        // Display the default form of three long date formats.
        foreach (var fmt in formats)
            Console.WriteLine(dateValue.ToString(fmt, dtfi));

        Console.WriteLine();

        // Modify the long date pattern.
        dtfi.LongDatePattern = originalLongDatePattern + " g";
        foreach (var fmt in formats)
            Console.WriteLine(dateValue.ToString(fmt, dtfi));

        Console.WriteLine();

        // Change A.D. to C.E. (for Common Era)
        dtfi.LongDatePattern = originalLongDatePattern + @" 'C.E.'";
        foreach (var fmt in formats)
            Console.WriteLine(dateValue.ToString(fmt, dtfi));
    }
}
// The example displays the following output:
//       Saturday, May 18, 2013
//       Saturday, May 18, 2013 1:30 PM
//       Saturday, May 18, 2013 1:30:00 PM
//
//       Saturday, May 18, 2013 A.D.
//       Saturday, May 18, 2013 A.D. 1:30 PM
//       Saturday, May 18, 2013 A.D. 1:30:00 PM
//
//       Saturday, May 18, 2013 C.E.
//       Saturday, May 18, 2013 C.E. 1:30 PM
//       Saturday, May 18, 2013 C.E. 1:30:00 PM

日付と時刻文字列の解析

解析では、日付と時刻の文字列表現を DateTime 値または DateTimeOffset 値に変換します。 これらの型には、解析操作をサポートするための ParseTryParseParseExactTryParseExact メソッドが含まれます。 Parse メソッドと TryParse メソッドは、さまざまな形式を持つ文字列を変換しますが、 ParseExact および TryParseExact には、文字列に書式が定義されている必要があります。 解析操作が失敗した場合、 ParseParseExact は例外をスローしますが、TryParseTryParseExactfalse を返します。

解析メソッドは、DateTimeStyles 列挙値を暗黙的または明示的に使用して、解析する文字列に存在できるスタイル要素 (先頭、末尾、内側の空白など) と、解析された文字列または不足している要素を解釈する方法を決定します。 Parse メソッドまたは TryParse メソッドを呼び出すときに DateTimeStyles 値を指定しない場合、既定値は DateTimeStyles.AllowWhiteSpacesです。これは、 DateTimeStyles.AllowLeadingWhiteDateTimeStyles.AllowTrailingWhite、および DateTimeStyles.AllowInnerWhite フラグを含む複合スタイルです。 ParseExact メソッドと TryParseExact メソッドの場合、既定値は DateTimeStyles.None です。入力文字列は、特定のカスタム日時書式指定文字列に正確に対応している必要があります。

また、解析メソッドは、解析する文字列内に現れる可能性のある特定の記号とパターンを定義する DateTimeFormatInfo オブジェクトを暗黙的または明示的に使用します。 DateTimeFormatInfo オブジェクトを指定しない場合、現在のカルチャの DateTimeFormatInfo オブジェクトが既定で使用されます。 日付と時刻の文字列の解析の詳細については、個々の解析メソッド (DateTime.ParseDateTime.TryParseDateTimeOffset.ParseExactDateTimeOffset.TryParseExact など) を参照してください。

次の例は、日付と時刻の文字列を解析するカルチャに依存する性質を示しています。 en-US、en-GB、fr-FR、および fi-FI カルチャの規則を使用して、2 つの日付文字列を解析しようとします。 en-US カルチャで 2014 年 8 月 18 日と解釈される日付は、18 が月番号として解釈されるため、他の 3 つのカルチャでは FormatException 例外をスローします。 2015 年 1 月 2 日は、en-US カルチャでは最初の月の 2 日目として解析されますが、残りのカルチャでは 2 か月目の最初の日として解析されます。

using System;
using System.Globalization;

public class ParseEx1
{
    public static void Main()
    {
        string[] dateStrings = { "08/18/2014", "01/02/2015" };
        string[] cultureNames = { "en-US", "en-GB", "fr-FR", "fi-FI" };

        foreach (var cultureName in cultureNames)
        {
            CultureInfo culture = CultureInfo.CreateSpecificCulture(cultureName);
            Console.WriteLine("Parsing strings using the {0} culture.",
                              culture.Name);
            foreach (var dateStr in dateStrings)
            {
                try
                {
                    Console.WriteLine(String.Format(culture,
                                      "   '{0}' --> {1:D}", dateStr,
                                      DateTime.Parse(dateStr, culture)));
                }
                catch (FormatException)
                {
                    Console.WriteLine("   Unable to parse '{0}'", dateStr);
                }
            }
        }
    }
}
// The example displays the following output:
//       Parsing strings using the en-US culture.
//          '08/18/2014' --> Monday, August 18, 2014
//          '01/02/2015' --> Friday, January 02, 2015
//       Parsing strings using the en-GB culture.
//          Unable to parse '08/18/2014'
//          '01/02/2015' --> 01 February 2015
//       Parsing strings using the fr-FR culture.
//          Unable to parse '08/18/2014'
//          '01/02/2015' --> dimanche 1 février 2015
//       Parsing strings using the fi-FI culture.
//          Unable to parse '08/18/2014'
//          '01/02/2015' --> 1. helmikuuta 2015

日付と時刻の文字列は、通常、次の 2 つの理由で解析されます。

  • ユーザー入力を日付と時刻の値に変換するため。
  • 日付と時刻の値をラウンドトリップするため。つまり、以前に文字列としてシリアル化された日付と時刻の値を逆シリアル化するため。

以降のセクションでは、これら 2 つの操作について詳しく説明します。

ユーザー文字列を解析する

ユーザーが入力した日付と時刻の文字列を解析するときは、ユーザーが行った可能性のあるカスタマイズなど、ユーザーのカルチャ設定を反映する DateTimeFormatInfo オブジェクトを常にインスタンス化する必要があります。 それ以外の場合、日付と時刻オブジェクトの値が正しくない可能性があります。 ユーザーカルチャのカスタマイズを反映する DateTimeFormatInfo オブジェクトをインスタンス化する方法については、「DateTimeFormatInfo と動的データ」セクションを参照してください。

次の例は、ユーザー カルチャ設定を反映する解析操作と反映しない解析操作の違いを示しています。 この場合、既定のシステム カルチャは en-US ですが、ユーザーはコントロール パネルの [地域と言語] を使用して、短い日付パターンを既定の "M/d/yyyy" から "yy/MM/dd" に変更しています。 ユーザーがユーザー設定を反映する文字列を入力し、その文字列がユーザー設定を反映 (オーバーライド) する DateTimeFormatInfo オブジェクトによって解析されると、解析操作は正しい結果を返します。 ただし、文字列が標準の en-US カルチャ設定を反映する DateTimeFormatInfo オブジェクトによって解析される場合、解析メソッドは 14 を年の最後の 2 桁ではなく月の数として解釈するため、FormatException 例外をスローします。

using System;
using System.Globalization;

public class ParseEx2
{
    public static void Main()
    {
        string inputDate = "14/05/10";

        CultureInfo[] cultures = { CultureInfo.GetCultureInfo("en-US"),
                                 CultureInfo.CreateSpecificCulture("en-US") };

        foreach (var culture in cultures)
        {
            try
            {
                Console.WriteLine("{0} culture reflects user overrides: {1}",
                                  culture.Name, culture.UseUserOverride);
                DateTime occasion = DateTime.Parse(inputDate, culture);
                Console.WriteLine("'{0}' --> {1}", inputDate,
                                  occasion.ToString("D", CultureInfo.InvariantCulture));
            }
            catch (FormatException)
            {
                Console.WriteLine("Unable to parse '{0}'", inputDate);
            }
            Console.WriteLine();
        }
    }
}
// The example displays the following output:
//       en-US culture reflects user overrides: False
//       Unable to parse '14/05/10'
//
//       en-US culture reflects user overrides: True
//       '14/05/10' --> Saturday, 10 May 2014

日付と時刻のデータをシリアル化および逆シリアル化する

シリアル化された日付と時刻のデータはラウンドトリップする必要があります。つまり、シリアル化された値と逆シリアル化された値はすべて同じである必要があります。 日付と時刻の値が 1 つの時点を表す場合、逆シリアル化された値は、復元されたシステムのカルチャまたはタイム ゾーンに関係なく、同じ時点を表す必要があります。 日付と時刻のデータをラウンドトリップするには、InvariantInfo プロパティによって返されるインバリアント カルチャの規則を使用して、データを生成して解析する必要があります。 書式設定と解析の操作は、既定のカルチャの規則を反映するべきではありません。 既定のカルチャ設定を使用すると、データの移植性は厳しく制限され、データを正常に逆シリアル化できるのは、カルチャ固有設定がそのデータがシリアル化されたスレッドのものと同じスレッド上のみとなる可能性があります。 場合によっては、これは同じシステム上でもデータが正常にシリアル化および逆シリアル化できない可能性があることを意味します。

日付と時刻の値の時刻要素が有効な場合は、UTC に変換し、標準書式指定文字列 "o" または "r" 使用してシリアル化する必要もあります。 その後、解析メソッドを呼び出し、インバリアント カルチャと共に適切な書式指定文字列を provider 引数として渡すことで、時刻データを復元できます。

次の例は、日付と時刻の値をラウンドトリップするプロセスを示しています。 米国を監視するシステムで日付と時刻をシリアル化します。太平洋時間と現在のカルチャは en-US です。

using System;
using System.Globalization;
using System.IO;

public class SerializeEx1
{
    public static void Main()
    {
        StreamWriter sw = new StreamWriter(@".\DateData.dat");
        // Define a date and time to serialize.
        DateTime originalDate = new DateTime(2014, 08, 18, 08, 16, 35);
        // Display information on the date and time.
        Console.WriteLine("Date to serialize: {0:F}", originalDate);
        Console.WriteLine("Current Culture:   {0}",
                          CultureInfo.CurrentCulture.Name);
        Console.WriteLine("Time Zone:         {0}",
                          TimeZoneInfo.Local.DisplayName);
        // Convert the date value to UTC.
        DateTime utcDate = originalDate.ToUniversalTime();
        // Serialize the UTC value.
        sw.Write(utcDate.ToString("o", DateTimeFormatInfo.InvariantInfo));
        sw.Close();
    }
}
// The example displays the following output:
//       Date to serialize: Monday, August 18, 2014 8:16:35 AM
//       Current Culture:   en-US
//       Time Zone:         (UTC-08:00) Pacific Time (US & Canada)

ブリュッセル、コペンハーゲン、マドリード、パリのタイム ゾーンで現在のカルチャが fr-FR であるシステム上のデータを逆シリアル化します。 復元日は元の日付より 9 時間遅れています。これは、UTC から UTC より 8 時間遅れた時刻から UTC の 1 時間前までのタイム ゾーン調整を反映しています。 元の日付と復元された日付の両方が、同じ時点を表します。

using System;
using System.Globalization;
using System.IO;

public class SerializeEx2
{
    public static void Main()
    {
        // Open the file and retrieve the date string.
        StreamReader sr = new StreamReader(@".\DateData.dat");
        String dateValue = sr.ReadToEnd();

        // Parse the date.
        DateTime parsedDate = DateTime.ParseExact(dateValue, "o",
                              DateTimeFormatInfo.InvariantInfo);
        // Convert it to local time.
        DateTime restoredDate = parsedDate.ToLocalTime();
        // Display information on the date and time.
        Console.WriteLine("Deserialized date: {0:F}", restoredDate);
        Console.WriteLine("Current Culture:   {0}",
                          CultureInfo.CurrentCulture.Name);
        Console.WriteLine("Time Zone:         {0}",
                          TimeZoneInfo.Local.DisplayName);
    }
}
// The example displays the following output:
//    Deserialized date: lundi 18 août 2014 17:16:35
//    Current Culture:   fr-FR
//    Time Zone:         (UTC+01:00) Brussels, Copenhagen, Madrid, Paris