我遇到的问题可能是由于我对DateTime.ToShortTimeString()方法如何工作的误解。使用此函数格式化时间字符串时,我假设它将遵循Windows 7格式设置中的“短时间”设置
Control Panel -> Clock, Language and Region -> Region and Language -> Formats Tab.
然而,.NET似乎选择了一种不基于此设置的短时间格式,而是基于当前的文化:
Region and Language -> Location -> Current Location
我在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)
我使用了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();
}
更新 根据迈克的评论,我采用了以下方法改编了上述方法:
以下两行
string sixAmString = sixAm.ToShortTimeString();
string sixPmString = sixPm.ToShortTimeString();
已更改为
string sixAmString = sixAm.ToString("t", culture);
string sixPmString = sixPm.ToString("t", culture);
我还将culture变量更改为使用CultureInfo.CurrentUICulture。
这不幸的是没有我想象的那么好,无论Windows 7的Formats选项卡中的Short Time配置如何输出都是:
Culture: en-US, 6AM: 6:00 AM, 6PM: 6:00 PM
看起来CultureInfo.CurrentUICulture始终是en-US。
答案 0 :(得分:5)
回答你的第二个问题是
DateTimeFormat.Format(DateTime.Now, "t", CultureInfo.CurrentUICulture);
或
DateTime.Now.ToString("t", CultureInfo.CurrentUICulture);
使用接受CultureInfo的显式方法实际上总是更好。没有一致性.Net选择默认使用的是CurrentCulture或CurrentUICulture或InvarinatCulture。
让答案充分。我还将概述文化之间的差异。
所以CurrentCulture是“控制面板 - >时钟,语言和区域 - >区域和语言 - >格式选项卡。”这是您期望计算的文化。例如,您可以在美国进行会计处理,因此您可以在美国进行配置。
CurrentUICulture是“地区和语言 - >显示语言”,意味着当您从乌克兰移民时,您希望您的应用程序在UA中本地化(但所有计算仍在美国)。
InvariantCulture是所谓的文化不可知的语言环境。您应该使用它来存储信息等。实际上它是En-US。
注意:我在Windows中的每个设置都可能出错。但你可能有了一个主意。
答案 1 :(得分:2)
我很确定在DateTime.ToShortTimeString()或DateTime.ToString(“t”)中没有使用短时格式字符串是一个错误,因为它是在.NET framework 4.0中修复的。 / p>
答案 2 :(得分:1)
回答我的每个问题:
1)我对.NET和Windows格式的误解是什么?
简短的回答是,“区域和语言”设置中的“短时间”设置与.NET的ShortTimePattern属性之间没有任何关联。但是,LongTimePattern属性由“长时间”设置决定。
我采用上述方法将两条格式化行替换为:
string sixAmString = sixAm.ToString("T", culture.DateTimeFormat);
string sixPmString = sixPm.ToString("T", culture.DateTimeFormat);
这是输出:
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
this article的底部向我解释了这个问题。
2)根据操作系统设置创建短格式时间字符串(HH:mm或hh:mm tt)的最佳解决方案是什么?
我不知道最佳解决方案,但我创建了以下函数,将LongTimeFormat转换为ShortTimeFormat,从而允许应用程序在更改“长时间”时遵循用户选项(尽管它不会跟踪“短时间”设置)。
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);
}
进行上述更改后的输出:
Culture: en-GB, 6AM: 06:00, 6PM: 18:00 Culture: en-GB, 6AM: 06:00 AM, 6PM: 06:00 PM
P / Invoke选项是使用GetTimeFormat使用DateTime.ToString(Format)传递TIME_NOSECONDS,如上所述。我没有测试过这个,因为我宁愿避免使用P / Invoke。