DateTimeInvalidLocalFormatÂ
The DateTimeInvalidLocalFormat MDA is activated when a DateTime instance that is stored as a Universal Coordinated Time (UTC) is formatted using a format that is intended to be used only for local DateTime instances. This MDA is not activated for unspecified or default DateTime instances.
Symptom
An application is manually serializing a UTC DateTime instance using a local format:
DateTime myDateTime = DateTime.UtcNow;
Serialize(myDateTime.ToString("yyyy-MM-dd'T'HH:mm:ss.fffffffzzz"));
Cause
The 'z' format for the System.DateTime.ToString method includes the local time zone offset, for example, "+10:00" for Sydney time. As such, it will only produce a meaningful result if the value of the DateTime is local. If the value is UTC time, System.DateTime.ToString includes the local time zone offset, but it does not display or adjust the time zone specifier.
Resolution
UTC DateTime instances should be formatted in a way that indicates that they are UTC. The recommended format for UTC times to use a 'Z' to denote UTC time:
DateTime myDateTime = DateTime.UtcNow;
Serialize(myDateTime.ToString("yyyy-MM-dd'T'HH:mm:ss.fffffffZ"));
There is also an "o" format that serializes a DateTime making use of the Kind property that serializes correctly regardless of whether the instance is local, UTC, or unspecified:
DateTime myDateTime = DateTime.UtcNow;
Serialize(myDateTime.ToString("o"));
Effect on the Runtime
This MDA does not affect the runtime.
Output
There is no special output as a result of this MDA activating., However, the call stack can be used to determine the location of the ToString call that activated the MDA.
Configuration
<mdaConfig>
<assistants>
<dateTimeInvalidLocalFormat />
</assistants>
</mdaConfig>
Example
Consider an application that is indirectly serializing a UTC DateTime value by using the XmlConvert or DataSet class, in the following manner.
DateTime myDateTime = DateTime.UtcNow;
String serialized = XMLConvert.ToString(myDateTime);
The XmlConvert and DataSet serializations use local formats for serialization by default. Additional options are required to serialize other kinds of DateTime values, such as UTC.
For this specific example, pass in XmlDateTimeSerializationMode.RoundtripKind
to the ToString
call on XmlConvert
. This serializes the data as a UTC time.
If using a DataSet, set the DateTimeMode property on the DataColumn object to Utc.
DateTime myDateTime = DateTime.UtcNow;
String serialized = XmlConvert.ToString(myDateTime,
XmlDateTimeSerializationMode.RoundtripKind);