【问题标题】:Where is the system locale/culture set for .Net.Net 的系统区域设置/文化设置在哪里
【发布时间】:2010-02-18 12:02:12
【问题描述】:

我对安装在英国服务器上的 c# 程序集(使用 Visual Studio 2005 编写的 .net 2.0)有疑问,应该使用英国区域设置。

我的代码所做的是将 dd/MM/yyyy 格式的日期转换为 utc。即 yyyy-mm-dd。问题出现在像 16/02/2010 这样的日期,其中组件无法转换日期并返回错误。调试后我意识到,由于一个奇怪的原因,System.CultureInfo 返回的 CultureInfo 是 en-US。

我可以使用以下方式以编程方式更改这些设置:

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB", false); 

我的代码运行良好。

但是我不想一直这样做,因为我的系统应该是英国的。不是我们。 那么,如何将 .Net 框架的默认文化更改为默认 en-GB 而不是 en-US ?

有关信息:

  • 我已尝试更新 machine.config 文件并为全球化部分指定culture=en-GB(它被设置为中性),但它也不起作用[已经为 1.1 和 2.0 做过] 但这是可能的我没有正确更改它。
  • 我已经验证了我的 windows 区域设置,它们肯定设置为英国,日期为 dd/MM/yyyy
  • 我在虚拟服务器中运行并验证了我的主机系统。它也设置为英国

编辑:

关于上下文的一些额外细节。有问题的程序集是通过 COM 互操作从作为 COM+ 应用程序运行的本机 C++ 第三方组件调用的。

【问题讨论】:

  • 看看问题是来自 C++/COM 环境还是操作系统可能会很有趣。如果您只是使用 Console.WriteLine(Thread.CurrentThread.CurrentCulture.DisplayName); 编写一个简单的控制台应用程序怎么办?它显示了什么?

标签: c# .net locale


【解决方案1】:

服务器配置不正确。控制面板 + 区域和语言,位置选项卡。改变这个可能有点棘手。服务器很可能是故意配置错误的。在做任何事情之前先与服务器管理员交谈。

您的后备计划是使用采用 IFormatProvider 参数的 DateTime.TryParse() 方法重载。传递 CultureInfo.GetCultureInfo("en-gb").DateTimeFormat.

【讨论】:

    【解决方案2】:

    要为所有页面设置UI文化和文化,在Web.config文件中添加一个全球化部分,然后设置uiculture和culture属性,如下例所示:

    <globalization uiCulture="en" culture="en-GB" />

    【讨论】:

    • 有问题的代码没有在 ASP.NET 中运行,所以没有 web.config 文件,我猜这个设置也可以在应用程序的配置文件中设置。我将在有关调用上下文的问题中添加一些额外的细节。
    • 最佳答案恕我直言,如果您的系统具有不同的文化,这也是获取可搜索错误消息的好方法;另外,您可能会因代码库中可能存在的System.Globalization 相关错误而提前崩溃
    【解决方案3】:

    嗯,根据API Docs

    当一个线程启动时,它的文化最初是通过使用 Windows API 中的GetUserDefaultLCID 来确定的。

    此方法从(顾名思义)用户的默认语言环境派生它的语言环境,我假设它位于控制面板中。 注意:这与 UI 区域设置不同。

    【讨论】:

      【解决方案4】:

      感谢您的回答(安迪代表我发布了这个问题)。这确实是区域设置的问题,但既不是我连接的用户,也不是运行该进程的用户。那太容易了。看起来默认用户仍然是 en-US。我通过单击高级选项卡中的复选框“将设置应用于当前用户和默认用户...”并重新启动服务器进行了重置。 System.Globalization.CultureInfo 现在返回 {en-GB}。并且 MyDate.ToString(yyyy-mm-dd) 可以正常工作,无论日期是作为 dd/MM/yyyy 还是 dd-MM-yyyy 或 yyyy-MM-dd 传递,而无需解析。

      不过,非常感谢你们提出的确实有效的建议(ParseExact 等)。它们对于我无法以很好的方式处理的其他日期格式(yyyyMMdd)非常有帮助。

      马克

      【讨论】:

      • 对默认用户设置的有趣且有价值的观察
      【解决方案5】:

      我相信这是由 System.Globalization.CultureInfo.InstalledUICulture 表示的,所以如果没有别的,也许你可以将它复制到线程的当前文化中。我很惊讶您发现线程文化与已安装文化不同的情况。也许您的代码在改变文化的进程中运行?

      运行代码的帐户可能具有与系统默认设置不同的区域设置。你检查过吗?

      【讨论】:

      • 我不确定第一个建议是否与明确设置文化有很大不同。 可能用户帐号设置错误,我会检查。
      【解决方案6】:

      您无需更改 CurrentCulture 即可进行转换。如果您确定日期的格式为“dd/MM/yyyy”,您可以使用

      DateTime dtTemp = DateTime.ParseExact(dateString, "dd/MM/yyyy", null) // in order not to have to specify a FormatProvider
      

      然后使用

      dtTemp.ToString("yyyy-MM-dd")
      

      这样,无论 CurrentCulture 是什么,您都不会遇到问题。但是,如果您不确定日期的格式是“dd/MM/yyyy”,而是基于 CurrentCulture 短日期格式,那么您应该使用

      DateTime dtTemp = DateTime(dateString, CurrentCulture.DateTimeFormat.ShortDatePattern, CurrentCulture.DateTimeFormat);
      

      【讨论】:

      • 我喜欢这个实用的解决方案并思考它,它可能是实现它的最佳方式,因为输入/输出格式确实是固定的。我仍然想知道为什么系统语言环境没有按我的预期工作。
      • 我想出了这个解决方法,在系统选择的区域设置要求格式为“dd/MM/yyyy”但用户选择日期格式为“MM/ dd/yyyy”。所以我不能真正相信当前的文化。这在 Windows 7 中是可能的,我认为在 XP 中也是如此。
      • 关闭,但不完全正确;要获得文字“/”,您应该使用格式“dd'/'MM'/'yyyy”,并将“/”字符指定为文字(在单引号中)。 “/”是日期格式替换字符(如“dd”等),替换为当前文化日期分隔符,可以是“-”或“.”;如果你想要一个文字“/”,即不希望它被替换,那么你需要用单引号括起来。
      【解决方案7】:

      .net 框架中的程序集是文化中立的。

      你想用什么代码来转换日期? 如果您使用的是ParseTryParse,请尝试为其提供文化参数以了解日期。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-17
        • 1970-01-01
        • 2010-10-22
        • 1970-01-01
        • 2011-09-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多