代码之家  ›  专栏  ›  技术社区  ›  Paul Hollingsworth

如何删除System.Threading.Thread.CurrentThread.CurrentCulture上的DateTime.Parse依赖项

  •  2
  • Paul Hollingsworth  · 技术社区  · 15 年前

    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,而不管传入的是“不变量文化”。我觉得这太不直观了,我认为这是一个“错误”。

    5 回复  |  直到 15 年前
        1
  •  9
  •   AakashM    15 年前

    这个代码片段证明了DateTime.Parse使用Thread.CurrentThread.CurrentCulture,而不管传入的是“不变量文化”

    我不知道这个例子如何证明这一点。字符串传递给 DateTime.Parse 是不同的,所以不同的结果随之而来也就不足为奇了。

    第一个字符串的时间格式为 23.59.59 InvariantCulture 无法解析;第二个字符串的时间格式为 23:59:59 不变文化 可以

    编辑 另外,由于这显然是有区别的,所以我运行的是.NET2.0和.NET2.0生成的字符串 fo-FO en-US 分别是

    9999-12-31T23.59.59Z
    

    9999-12-31T23:59:59Z
    
        2
  •  1
  •   Scott M.    15 年前

    来自MSDN:

    文化不敏感。你的申请 按指定不变区域性 使用空字符串(“”)或按 不变量区域性检索实例 不变的文化。它是

    我找不到任何关于使用当前线程的区域性的参考,因为正如您所说的那样,这是违反直觉的。

    您可以(作为一种解决方法)缓存当前线程的区域性,将其设置为已知良好的区域性(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字符串的区域性,并且不会影响外部调用代码,因为从外部角度来看,区域性永远不会更改。

        3
  •  1
  •   Leopold Lerch    10 年前

    如果您不想在解析中尊重任何时区,可以使用

    var d = DateTime.Parse(s, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);
    

    var d = DateTime.Parse(s, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
    
        4
  •  0
  •   Dr Herbie    15 年前

    两种解析都使用 InvariantCulture ,这实际上是对“en-US”文化的硬编码引用(可能存在 不变文化 不是'恩我们',但我没有经过他们)。

    不变文化 new CultureInfo("en-US") 很明显为什么第一次解析不起作用。

        5
  •  0
  •   Daniel Rose    15 年前

    除了AakashM写的: