I have run into an issue that is probably due to my mis-understanding of how the DateTime.ToShortTimeString() method works. When formatting time strings with this function,
In answer to each of my questions:
1) What is my misunderstanding of .NET and Windows Formats?
The short answer is, there is no link between the "Short Time" setting in "Regional and Language" settings and .NET's ShortTimePattern property. However the LongTimePattern property is dictated by the "Long Time" setting.
I adapted the above method replacing the two formatting lines to:
string sixAmString = sixAm.ToString("T", culture.DateTimeFormat);
string sixPmString = sixPm.ToString("T", culture.DateTimeFormat);
Here is the output:
Culture: en-GB, 6AM: 06:00:00, 6PM: 18:00:00 // HH:mm:ss Culture: en-GB, 6AM: 06:00:00 AM, 6PM: 06:00:00 PM //hh:mm:ss tt
The bottom of this article explained the problem to me.
2) What is the best solution to create a short format time string (HH:mm or hh:mm tt) based upon the operating system setting?
I don't know about the best solution, but I created the following function that converts the LongTimeFormat to a ShortTimeFormat thus allowing an application to follow the users option if they change the "Long Time" (albeit it won't track the "Short Time" setting).
static string GetShortTimeString(DateTime ShortTimeString)
{
DateTimeFormatInfo dateTimeFormat = CultureInfo.CurrentCulture.DateTimeFormat;
string ShortTimePattern = dateTimeFormat.LongTimePattern.Replace(":ss", String.Empty);
ShortTimePattern = ShortTimePattern.Replace(":s", String.Empty);
return ShortTimeString.ToString(ShortTimePattern);
}
The output after making the above changes:
Culture: en-GB, 6AM: 06:00, 6PM: 18:00 Culture: en-GB, 6AM: 06:00 AM, 6PM: 06:00 PM
The P/Invoke option is to use GetTimeFormat passing the TIME_NOSECONDS using DateTime.ToString(Format) as above. I have not tested this as I would prefer to avoid using P/Invoke.