我的计算机配置的文化不是en-US
.
使用本机 Win32GetDateFormat
函数时,我得到正确格式的日期:
- 22//11//2011 4::42::53 P̰̃M]
这是对的; 也是 Windows 呈现它的方式:
任务栏
区域和语言设置
Windows资源管理器
外表
当我尝试使用我当前的语言环境将日期转换为 .NET 中的字符串时,例如:
DateTime.Now.ToString();
DateTime.Now.ToString(CultureInfo.CurrentCulture);
我得到一个不正确的日期:
- 22////11////2011 4::::42::::53 P̰̃M]
.NET 中的这个错误在 Windows 中使用有错误的 .NET 代码的任何地方都很明显:
Windows 事件查看器:
任务调度器:
SQL Server 管理工作室:
我如何使 .NET 不出错?
如何使用当前文化(正确)将日期和时间转换为字符串?
注意:允许用户将他们的Windows 设置为他们想要的任何区域设置首选项。就像现在一样,我的程序将无法正确处理 有效设置。告诉用户“不要那样做”是非常卑鄙的。
一个类似的例子来自 Delphi,它假设日期分隔符不能超过一个字符。当 Windows 配置了使用多个字符作为日期分隔符的语言环境时,例如:
- sk-SK(斯洛伐克 - 斯洛伐克):
.
日期应格式化为:
22. 11. 2011
代码库无法接受超过一个字符的日期分隔符,并回退到:
22/11/2011
在过去,有些人可能会建议您不要为这种边缘情况而烦恼。这样的建议对我来说毫无意义。
我会避免与想要通过更改标题来改变我的问题含义的人发生小便比赛。但问题不限于伪语言环境,专门用于查找应用程序中的错误。
奖金喋喋不休
以下是来自世界各地的独特日期格式列表:
- 11.11.25
- 11.25.2011
- 2011 年 11 月 25 日
- 2011.11.25
- 2011.11.25。
- 2011/11/25
- 2011-11-25
- 2011
- 25.11.11
- 25.11.2011
- 25.11.2011
- 2011 年 11 月 25 日。
- 25//11//2011
- 25/11 2011
- 25/11/2011
- 25/11/2554
- 25-11-11
- 25-11-2011
- 29/12/32
特别感兴趣的是最后一个不使用公历的例子:
- 阿拉伯语(沙特阿拉伯)
ar-SA
:29/12/32 02:03:07 - Divehi (马尔代夫)
dv-MV
: 29/12/32 14:03:07 - 达里语/普什图语(阿富汗)
prf-AF / ps-AF
:29/12/32 2:03:07 غ.و
尽管这些是您永远不必担心的极端情况。
2011 年 14 月 12 日更新:
该错误的另一个演示是Datetime.Parse
无法解析DateTime.ToString
:
String s = DateTime.Today.ToString("d"); //returns "14////12////2011"
DateTime d = DateTime.Parse(s); //expects "dd//MM//yyyy"
.Parse
抛出异常。
更新 02//8, 2012 09::56'12:
除了不正确之外,日期分隔符的任何使用都被弃用。来自 MSDN:
LOCALE_SDATE
Windows Vista 及更高版本:不推荐使用此常量。改为使用
LOCALE_SSHORTDATE
。自定义语言环境可能没有单个统一的分隔符。例如,“2006 年 12 月 31 日”这样的格式是有效的。LOCALE_STIME
Windows Vista 及更高版本:不推荐使用此常量。改为使用
LOCALE_STIMEFORMAT
。自定义语言环境可能没有单个统一的分隔符。例如,“03:56'23”这样的格式是有效的。