问题描述
我遇到一个问题,可能是由于我对DateTime.ToShortTimeString()方法的工作原理的误解。当使用此功能格式化时间字符串时,我假设它将遵守Windows 7的格式设置中的短时间设置控制面板 - >时钟,语言和区域 - >区域和语言 - >格式选项卡。
但是,.NET似乎选择不是基于此设置的短时间格式,而是基于当前文化:
区域和语言 - >位置 - >当前位置
在Windows 7 RC上进行了一些测试:
文化:en-GB,6AM:06:00,6PM:18:00 // HH :mm(英国)
文化:en-GB,6AM:06:00,6PM:18:00 // hh:mm(英国)
文化:en-US,6AM:6: 00 AM,6PM:6:00 PM // HH:mm(美国)
文化:en-US,6AM:6:00 AM,6PM:6:00 PM // hh:mm(美国)
文化:el-GR,6AM:6:00πμ,6PM:6:00μμ// HH:mm(希腊)
文化:el-GR,6AM:6:00πμ,6PM: 6:00μμ// hh:mm(希腊)
我用el-GR因为那是报告问题的用户的文化,他也在Vista SP2和Win 7 RC上测试了相同的结果。
折叠真的:
1)我对.NET和Windows格式的误解是什么?
2)基于操作系统,创建短格式时间字符串(HH:mm或hh:mm tt)的最佳解决方案是理想的,这应该在Mono中工作,所以我宁愿避免从注册表读取或P / Invoke。
用于生成上述内容的方法,供将来参考和测试。
[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();
}
更新:
根据Mike的下面的评论我修改了上述方法,并进行了以下更改:
以下两行
code> string sixAmString = sixAm.ToShortTimeString();
string sixPmString = sixPm.ToShortTimeString();
更改为
code> string sixAmString = sixAm.ToString(t,culture);
string sixPmString = sixPm.ToString(t,culture);
我还将文化变量更改为使用CultureInfo.CurrentUICulture。
这不幸也没有像我所希望的那样工作,无论Windows 7的格式选项卡中的短时间配置如何,输出都是:
文化:美国,6AM:6:00 AM,6PM:6:00 PM
在回答我的每个问题时:
1)我对.NET和Windows格式的误解是什么?
简短的答案是,有区域和语言设置中的短时间设置和.NET的ShortTimePattern属性之间没有链接。然而,LongTimePattern属性由长时间设置决定。
我将上述方法替换为两个格式行:
string sixAmString = sixAm.ToString(T,culture.DateTimeFormat);
string sixPmString = sixPm.ToString(T,culture.DateTimeFormat);
以下是输出:
文化:en-GB,6AM:06:00:00,6PM:18:00:00 // HH:mm:ss
文化:en-GB,6AM:06: 00 AM,6PM:06:00:00 PM // hh:mm:ss tt
向我解释了这个问题。
2)根据操作系统设置,创建短格式时间字符串(HH:mm或hh:mm tt)的最佳解决方案是什么?
我不知道最好的解决方案,但是我创建了以下功能,将LongTimeFormat转换为ShortTimeFormat,从而允许应用程序如果更改长时间,则遵循用户选项(虽然它赢了不要跟踪短时间设置)
静态字符串GetShortTimeString(DateTime ShortTimeString)
{
DateTimeFormatInfo dateTimeFo rmat = CultureInfo.CurrentCulture.DateTimeFormat;
string ShortTimePattern = dateTimeFormat.LongTimePattern.Replace(:ss,String.Empty);
ShortTimePattern = ShortTimePattern.Replace(:s,String.Empty);
return ShortTimeString.ToString(ShortTimePattern);
}
进行上述更改后的输出:
文化:en-GB,6AM:06:00,6PM:18:00
文化:en-GB,6AM:06:00 AM,6PM: 06:00 PM
P / Invoke选项是使用使用DateTime.ToString(Format)传递TIME_NOSECONDS,如上所述。我没有测试过,因为我宁愿避免使用P / Invoke。
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.
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.
这篇关于为什么DateTime.ToShortTimeString()在“区域和语言设置”中尊重短时间格式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!