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, I was assuming that it would respect the "Short Time" setting in Windows 7's Format settings
Control Panel -> Clock, Language and Region -> Region and Language -> Formats Tab.
However .NET seems to select a short time format not based upon this setting but based upon the current culture:
Region and Language -> Location -> Current Location
I did some testing on Windows 7 RC:
Culture: en-GB, 6AM: 06:00, 6PM: 18:00 // HH:mm (United Kingdom) Culture: en-GB, 6AM: 06:00, 6PM: 18:00 // hh:mm (United Kingdom) Culture: en-US, 6AM: 6:00 AM, 6PM: 6:00 PM // HH:mm (United States) Culture: en-US, 6AM: 6:00 AM, 6PM: 6:00 PM // hh:mm (United States) Culture: el-GR, 6AM: 6:00 πμ, 6PM: 6:00 μμ // HH:mm (Greece) Culture: el-GR, 6AM: 6:00 πμ, 6PM: 6:00 μμ // hh:mm (Greece)
I used el-GR as that was the culture that the user that reported the problem with, he also tested this on Vista SP2 and Win 7 RC with the same result.
The question is two-fold really: 1) What is my misunderstanding of .NET and Windows Formats? 2) What is the best solution to create a short format time string (HH:mm or hh:mm tt) based upon the operating system, ideally this should work in Mono so I would prefer to avoid reading from the registry or P/Invoke.
Method used to generate the above, for future reference and testing.
[STAThread]
static void Main(string[] args)
{
CultureInfo culture = CultureInfo.CurrentCulture;
DateTime sixAm = new DateTime(2009, 07, 05, 6, 0, 0); // 6AM
DateTime sixPm = new DateTime(2009, 07, 05, 18, 0, 0); // 6PM
string sixAmString = sixAm.ToShortTimeString();
string sixPmString = sixPm.ToShortTimeString();
string format = "Culture: {0}, 6AM: {1}, 6PM: {2}";
string output = String.Format(format, culture, sixAmString, sixPmString);
Console.WriteLine(output);
Clipboard.Clear();
Clipboard.SetText(output);
Console.ReadKey();
}
Update: Based upon Mike's comments below I adapted the above method with the following changes:
The following two lines
string sixAmString = sixAm.ToShortTimeString();
string sixPmString = sixPm.ToShortTimeString();
Changed to
string sixAmString = sixAm.ToString("t", culture);
string sixPmString = sixPm.ToString("t", culture);
I also changed the culture variable to use CultureInfo.CurrentUICulture.
This unfortunatly didn't work as well as I had hoped, the output regardless of the configuration of Short Time in Windows 7's Formats tab was:
Culture: en-US, 6AM: 6:00 AM, 6PM: 6:00 PM
It seems the CultureInfo.CurrentUICulture is always en-US.