代码之家  ›  专栏  ›  技术社区  ›  John_

新服务器上的.NET全局区域性

  •  0
  • John_  · 技术社区  · 16 年前

    我们刚换了一台新服务器,一切都很顺利。然而,早些时候,我在试图将格式为“dd/mm/yyyy”的字符串转换为日期时遇到了一个.NET错误,现在我在本地web.config中更改了区域性设置,但我们要求它是全局的。

    我在哪里换这个?我假设machine.config,但在旧服务器上找不到任何熟悉的设置。

    还是应该查看服务器端并找到一个设置,将机器上的区域性设置为en-GB?

    =更新= 我已经更改了区域设置,但不幸的是它仍然失败。有没有一个machine.config全局设置可能会搞砸它?目前,它似乎正在使用不变量,并因此而失败。

    如果有任何帮助的话,我使用的是WindowsServer2008和iis7。

    正在使用的字符串是硬编码到页面中的,因为它是一次性网站注册表的结束日期。

    正在运行的代码如下:

    if (DateTime.Now > Convert.ToDateTime("26/04/2008 12:00"))
    

    非常简单,以前工作过无数次,只有在这个新的设置上才会发生这个错误。

    3 回复  |  直到 14 年前
        1
  •  2
  •   Alfred Myers    16 年前

    迁移服务器时,我建议您使用与以前相同的区域设置(控制面板)(如果可能的话)。只要这样,你就可以避免很多问题。

    但是,如果新服务器要承载其他需要其他区域设置的应用程序,或者由于新策略而必须承载其他区域设置,这可能是不可能的。

    在任何情况下,最好在所有Parse和ToString()调用期间显式指定适用的格式。

    甚至还有一个fxcop(和静态分析)规则。


    更新以反映有关问题的新信息:

    convert.todatetime是一个“便利”方法,实现如下:

    
    public static DateTime ToDateTime(string value)
    {
        if (value == null)
        {
            return new DateTime(0L);
        }
        return DateTime.Parse(value, CultureInfo.CurrentCulture);
    }
    
    

    请注意,它调用datetime.parse,并传递一个显式的CultureInfo(CultureInfo.CurrentCulture)。

    CultureInfo.CurrentCulture从Thread.CurrentThread.CurrentCulture获取它的值。

    您可以查看CultureInfo.CurrentCulture以了解它实际返回的CultureInfo和/或进一步调查以了解正在发生的情况,但另一方面,建议您 明确规定 将字符串解析为其他数据类型(如datetime、double等)时使用的格式化程序。

    正如我在原始答案中所说,有一个fxcop(静态分析)规则来检查是否缺少传递给方法的iformatProvider,这些方法具有接收其实例的重载: CA1305 .

    因此,我建议您按照以下几行重写代码:

    
    if (DateTime.Now > DateTime.Parse("26/04/2008 12:00", new CultureInfo("en-GB")))
    
        2
  •  1
  •   John_    16 年前

    最后(我不确定这是否是最好的方法),我必须从iis7中选择计算机,并将那里的全球化设置设置为en-GB。这确实解决了这个问题,而且除非另有说明,否则我的所有其他网站将来都将保留在这种文化中。

    请注意,我已经将计算机的区域设置更改为“UK”,但这并没有解决问题。

    不过,从现在开始,我将继续讨论阿尔弗雷德提出的将日期解析为特定文化的建议。

        3
  •  0
  •   Ian Boyd    14 年前

    应该指定在将字符串转换为日期时要使用的区域性。

    您应该使用的区域性取决于日期的格式。例如,如果要分析的所有日期都格式化为 斯洛伐克人 :

    String s = "24. 10. 2011";
    

    然后您需要像分析字符串一样分析它 斯洛伐克语(斯洛伐克) ( sk-SK 文化:

    //Bad:
    d = DateTime.Parse(s);
    
    //Good:
    d = DateTime.Parse(s, CultureInfo.CreateSpecificCulture("sk-SK")); //Slovak (Slovakia)
    

    如果你的约会都在 塔吉克语(塔吉克斯坦西里尔文) ,然后需要将其解析为 tg-Cryl-Tj :

    String s = "24.10.11"
    
    DateTime d = DateTime.Parse(s, CultureInfo.CreateSpecificCulture("tg-Cryl-Tj"));
    

    这就引出了一个问题:您使用的日期格式是什么?您不应该依赖服务器的区域设置,您应该决定您想要什么格式。

    //Bad
    String s = d.ToString();
    
    //Good
    String s = d.ToString(CultureInfo.CreateSpecificCulture("si-LK")); //Sinhala (Sri Lanka)
    
    //s = "2011-10-24 12:00:00 පෙ.ව."
    

    我怀疑你喜欢用英语做每件事。但是你必须决定英语的哪种变体:

    • en-IA (英语-印度): 24-10-2011 15:19:52
    • en-BZ (伯利兹英语): 24/10/2011 03:19:52 PM
    • en-AU (澳大利亚英语): 24/10/2011 3:19:52 PM
    • en-NZ (新西兰英语): 24/10/2011 3:19:52 p.m.
    • en-GB (英国英语): 24/10/2011 15:19:52
    • en-ZA (南非英语): 2011/10/24 03:19:52 PM
    • en-US (美国英语): 10/24/2011 3:19:52 PM

    但是,如果您真的无法决定将日期转换为字符串时要使用什么区域性,反之亦然,并且这些日期从未打算向用户显示,那么您可以使用 不变文化 :

    String s = "10/24/2011" //invariant culture formatted date
    
    d = DateTime.Parse(s, CultureInfo.InvariantCulture); //parse invariant culture date
    
    s = d.ToString(CultureInfo.InvariantCulture); //convert to invariant culture string