请考虑以下代码:
class Program
{
static void Main(string[] args)
{
try
{
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("fo-FO");
var s = DateTime.MaxValue.ToString("yyyy-MM-ddTHH:mm:ssZ");
var d = DateTime.Parse(s, CultureInfo.InvariantCulture);
Console.WriteLine("Was able to parse with fo-FO");
}
catch (Exception e)
{
Console.WriteLine("Exception: {0}", e);
}
try
{
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
var s = DateTime.MaxValue.ToString("yyyy-MM-ddTHH:mm:ssZ");
var d = DateTime.Parse(s, CultureInfo.InvariantCulture);
Console.WriteLine("Was able to parse with en-US");
}
catch (Exception e)
{
Console.WriteLine("Exception: {0}", e);
}
}
}
输出结果为:
Exception: System.FormatException: String was not recognized as a valid DateTime.
at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles)
at System.DateTime.Parse(String s, IFormatProvider provider)
at DateTimeTest2.Program.Main(String[] args) in C:\Projects\DateTimeTest2\DateTimeTest2\Program.cs:line 17
Was able to parse with en-US
此代码片段证明DateTime.Parse使用Thread.CurrentThread.CurrentCulture,而不管传入“InvariantCulture”的事实。我发现这非常不直观,我认为这是一个“错误”。
为什么我们必须传入CultureInfo,如果事实上它被DateTime.Parse忽略了?有没有办法以独立于CurrentCulture的方式调用DateTime.Parse?
答案 0 :(得分:9)
此代码片段证明DateTime.Parse使用Thread.CurrentThread.CurrentCulture,无论是否传递“InvariantCulture”
我不确定这个例子是如何证明的。传递给DateTime.Parse
的字符串是不同的,所以不同的结果随之而来并不奇怪。
第一个字符串的格式为23.59.59
,显然InvariantCulture
无法解析;第二个字符串的格式为23:59:59
,InvariantCulture
可以解析。有什么问题?
编辑要添加,因为显然它有所不同,我运行的是.NET 2.0,fo-FO
和en-US
生成的字符串分别为
9999-12-31T23.59.59Z
和
9999-12-31T23:59:59Z
答案 1 :(得分:1)
:
不变的文化是 文化不敏感。你的申请 指定不变文化 使用空字符串(“”)或by的名称 它的语言标识符。 InvariantCulture检索实例 不变的文化。它是 与英语相关联 但没有任何国家/地区。
我找不到任何关于使用当前线程文化的参考,因为这与你说的那样是违反直觉的。
你可以(作为一种解决方法)缓存当前线程的文化,将其设置为已知的良好文化(en-US),执行解析,然后将线程的文化设置回旧值。
CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
var s = DateTime.MaxValue.ToString("yyyy-MM-ddTHH:mm:ssZ");
var d = DateTime.Parse(s, CultureInfo.InvariantCulture);
System.Threading.Thread.CurrentThread.CurrentCulture = ci;
这将保证您知道正在使用什么文化来解析DateTime字符串,并且不会影响外部调用代码,因为文化永远不会从外部角度更改。
答案 2 :(得分:1)
如果您不想在解析中考虑任何时区,可以使用
var d = DateTime.Parse(s, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);
或
var d = DateTime.Parse(s, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
答案 3 :(得分:0)
两个解析都使用InvariantCulture
,这实际上是对'en-US'文化的硬编码引用(可能有InvariantCulture
不是'en-US'但是我没有来到他们身边)。
将InvariantCulture
的使用替换为new CultureInfo("en-US")
,很明显为什么第一个解析不起作用。
答案 4 :(得分:0)
除了AakashM所写的内容:
我尝试在.NET 3.5 SP1中运行它。在第二种情况下,我得到一个System.FormatException,声明DateTime的值超出范围。