Why not just use the round-trip format specifier ("o", "o") ?
The standard format specifier โOโ or โoโ is a custom date and time format string using a template that stores time zone information and emits a result string that complies with ISO 8601. For DateTime values, this format specifier is for storing date and time values along with the DateTime.Kind property in the text. You can parse a formatted string using the DateTime.Parse (String, IFormatProvider, DateTimeStyles) or DateTime.ParseExact method, if the styles parameter is set to DateTimeStyles.RoundtripKind.
The standard format specifier "O" or "o" corresponds to the user-format string "yyyy" - "MM" - "dd'T'HH": 'mm': 'ss..fffffffK for DateTime values โโand to the user-format string "yyyy" - "MM" - "dd'T'HH": 'mm': 'ss .. fffffffzzz "for DateTimeOffset values. This line contains pairs of single quotes that enclose individual characters, such as hyphens, colons and the letter" T ", indicate that a single character is a literal that cannot be changed. Apostrophes are not displayed on the output line.
The standard format specifier is O "or" o "(and the custom format string" yyyy '-' MM '-' dd'T'HH ':' mm ':' ss '.' FffffffK) takes advantage of the three ways that ISO 8601 represents time zone information to save the Kind property for DateTime values:
public class Example { public static void Main() { DateTime dat = new DateTime(2009, 6, 15, 13, 45, 30, DateTimeKind.Unspecified); Console.WriteLine("{0} ({1}) --> {0:O}", dat, dat.Kind); DateTime uDat = new DateTime(2009, 6, 15, 13, 45, 30, DateTimeKind.Utc); Console.WriteLine("{0} ({1}) --> {0:O}", uDat, uDat.Kind); DateTime lDat = new DateTime(2009, 6, 15, 13, 45, 30, DateTimeKind.Local); Console.WriteLine("{0} ({1}) --> {0:O}\n", lDat, lDat.Kind); DateTimeOffset dto = new DateTimeOffset(lDat); Console.WriteLine("{0} --> {0:O}", dto); } }