.NET中系统的区域设置/文化是在哪里设置的?

10
我有一个问题,涉及一个使用Visual studio 2005编写的c#程序集(.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(它被设置为 neutral),但也不起作用[已在1.1和2.0中完成],但可能我没有正确更改它。 - 我已验证我的 Windows 区域设置,它们明确设置为带有日期的英国格式 dd/MM/yyyy。 - 我正在虚拟服务器上运行,并已验证我的主机系统。 它也是英国风格。
编辑: 关于上下文的一些额外细节。所涉及的程序集通过 COM 互操作从运行为 COM+ 应用程序的本地 C++ 第三方组件调用。

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

5

服务器配置不正确。控制面板+区域和语言,位置选项卡。更改可能有点棘手。服务器可能是有意进行了错误配置的。在采取任何行动之前,请首先与服务器管理员联系。

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


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

涉及的代码不在ASP.NET中运行,因此没有web.config文件。我猜想该设置也可以在应用程序的配置文件中设置。我将在问题中添加一些关于调用上下文的额外细节。 - andynormancx
在我看来,最佳答案是这样的。如果您的系统具有不同的文化背景,这也是获取可搜索错误消息的好方法;此外,您还可以获得与 System.Globalization 相关的早期崩溃,以便检测代码库中可能存在的错误。 - mfeineis

3
根据API文档,当一个线程被启动时,它的文化初始值是由Windows API中的GetUserDefaultLCID决定的。该方法从用户默认语言环境中派生其区域设置,我认为这个设置在控制面板中。注意:这与UI语言环境不同。

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

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

Marc


有关默认用户设置的有趣且有价值的观察 - Andrzej Martyna

2
我认为这可以通过 System.Globalization.CultureInfo.InstalledUICulture 来表示,因此如果没有其他办法,您可以将其复制到线程的当前语言环境中。我很惊讶您发现了线程的语言环境与安装的语言环境不同的情况。也许您的代码正在运行在更改了语言环境的进程中?
有可能运行代码的帐户具有不同于系统默认设置的区域设置。您检查过了吗?

我不确定第一个建议是否真的与显式设置区域文化信息有很大的区别。用户账户设置错误是有可能的,我会检查一下。 - andynormancx

1

您不必更改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")

这样做,无论当前文化是什么,您都不会遇到问题。但是,如果您不确定日期是否采用“dd/MM/yyyy”格式,而是基于当前文化的短日期格式,则应使用

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

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

0

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

您要转换哪个代码日期? 如果您正在使用ParseTryParse,请尝试提供文化参数以使其理解日期。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接