dateTimeInvalidLocalFormat MDA

dateTimeInvalidLocalFormat MDA は、世界協定時刻 (UTC) として格納されている DateTime インスタンスが、ローカル DateTime インスタンス専用の形式で書式指定されたときにアクティブになります。 この MDA は、未指定または既定の DateTime インスタンスに対してはアクティブになりません。

症状

アプリケーションで、次のようなローカル形式を使用して UTC DateTime インスタンスを手動でシリアル化しています。

DateTime myDateTime = DateTime.UtcNow;  
Serialize(myDateTime.ToString("yyyy-MM-dd'T'HH:mm:ss.fffffffzzz"));  

原因

DateTime.ToString メソッドの 'z' 形式には、ローカル タイム ゾーン オフセット (たとえば、シドニー時間の場合は "+10:00") が含まれます。 そのため、DateTime の値がローカルの場合にのみ、有意な結果が生成されます。 値が UTC 時刻の場合、DateTime.ToString には、ローカル タイム ゾーン オフセットが含まれますが、タイム ゾーン指定子の表示や調整は行われません。

解決方法

UTC DateTime インスタンスが UTC であることを示すように書式設定する必要があります。 UTC 時刻の形式としては、次のように 'Z' を使用して UTC 時刻を示すようにすることをお勧めします。

DateTime myDateTime = DateTime.UtcNow;  
Serialize(myDateTime.ToString("yyyy-MM-dd'T'HH:mm:ss.fffffffZ"));  

また、インスタンスがローカル、UTC、未指定のいずれの場合でも正しくシリアル化する Kind プロパティを利用して DateTime をシリアル化する "o" 形式もあります。

DateTime myDateTime = DateTime.UtcNow;  
Serialize(myDateTime.ToString("o"));  

ランタイムへの影響

この MDA はランタイムに影響しません。

出力

この MDA がアクティブになっても特別な出力は生成されませんが、呼び出し履歴を使用すると、この MDA をアクティブにした ToString 呼び出しの位置を確認できます。

構成

<mdaConfig>  
  <assistants>  
    <dateTimeInvalidLocalFormat />  
  </assistants>  
</mdaConfig>  

次のように、XmlConvert または DataSet クラスを使用して UTC DateTime 値を間接的にシリアル化するアプリケーションについて考えてみます。

DateTime myDateTime = DateTime.UtcNow;  
String serialized = XMLConvert.ToString(myDateTime);  

XmlConvertDataSet のシリアル化では、既定でシリアル化用のローカル形式を使用します。 UTC など、他の種類の DateTime 値をシリアル化する場合は、追加のオプションが必要です。

この特定の例では、XmlConvert での ToString 呼び出しに XmlDateTimeSerializationMode.RoundtripKind を渡します。 これで、データが UTC 時刻としてシリアル化されます。

DataSet を使用する場合は、DataColumn オブジェクトの DateTimeMode プロパティを Utc に設定します。

DateTime myDateTime = DateTime.UtcNow;  
String serialized = XmlConvert.ToString(myDateTime,
    XmlDateTimeSerializationMode.RoundtripKind);  

関連項目