It all started with simple requirement: there is UTC time string (e.g. 21:00) and you should parse it into UTC DateTime. Simplest code ever:
var time = DateTime.ParseExact(text, "HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.NoCurrentDateDefault);
Only issue is that it does not work. While it looks good on first look, more careful investigation shows that its type is not
Unspecified. While this might not seem as a major pain, it does make a difference.
Let’s assume that you send proper UTC time to some function that does
time.ToUniversalTime(). Function will just return exactly same time back. If you do same with
Unspecified time, function will adjust it for time zone and you will get back completely different time than what you started with.
Well, fixing this is easy, just add
var time = DateTime.ParseExact(text, "HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.NoCurrentDateDefault | DateTimeStyles.AssumeUniversal);
Unfortunately it does not work. While description says “If no time zone is specified in the parsed string, the string is assumed to denote a UTC”, flag actually causes our time to be
To properly parse time you need one more flag:
var time = DateTime.ParseExact(text, "HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.NoCurrentDateDefault | DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
This will finally cause our time to be of
Code sample is available.