C# 本地化系统上的日期时间解析
我们有一个生成报告的web应用程序。数据取自数据库 当我们在本地化系统上运行web应用程序时,它会崩溃。我们在DateTime.Parse(dateString)上跟踪了这个问题;打电话 数据库中存储的日期在某种程度上取决于机器的语言环境 在英语系统中,日期存储为MM/DD/YYYY(06/25/2009),这是完全正常的 在俄罗斯系统中,日期存储为MM.DD.YYYY(06.25.2009)。这很奇怪,因为俄语系统中短日期格式的默认设置(我选中)是dd.MM.yyyy。。。所以应该是2009年6月25日。我不明白为什么它接受默认的分隔符(.)而不是默认的日期格式 那么无论如何,我如何在本地化系统上解析日期字符串呢?如果我使用俄罗斯cultureinfo,它仍然会抛出一个错误,因为它预期的是dd.MM.yyyyyC# 本地化系统上的日期时间解析,c#,.net,datetime,C#,.net,Datetime,我们有一个生成报告的web应用程序。数据取自数据库 当我们在本地化系统上运行web应用程序时,它会崩溃。我们在DateTime.Parse(dateString)上跟踪了这个问题;打电话 数据库中存储的日期在某种程度上取决于机器的语言环境 在英语系统中,日期存储为MM/DD/YYYY(06/25/2009),这是完全正常的 在俄罗斯系统中,日期存储为MM.DD.YYYY(06.25.2009)。这很奇怪,因为俄语系统中短日期格式的默认设置(我选中)是dd.MM.yyyy。。。所以应该是2009年
谢谢 永远不要在数据库中存储本地化的日期字符串。 必须将日期存储在日期列中,然后在显示数据时对其进行本地化 1.设置站点UI的区域设置 本例根据请求路径设置lang,但可能有其他机制
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
Dim lang As String
If HttpContext.Current.Request.Path.Contains("/en/") Then
lang = "en" 'english'
ElseIf HttpContext.Current.Request.Path.Contains("/pt/") Then
lang = "pt" 'portugues'
Else
lang = "es" 'español, the default for the site'
End If
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang)
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(lang)
End Sub
2.获取日期变量的输入
从文本输入中获取数据很容易,这是一个示例,但是使用日期验证器应该可以
dim theDate as date
if IsDate( txtDate.text ) then
theDate = DateTime.Parse(txtDate.text)
else
'throw exception or something
end if
编辑
既然你说你不能改变它的存储方式,你就有大麻烦了,除非你在数据库记录中有某种方式来告诉日期的格式。问题不在于分隔符,但当你找到2009年6月3日这样的日期时,你不知道是3月6日还是6月3日。这实际上取决于RDBMS。查看是否可以让数据库将日期存储在所选的不变区域性或特定(非更改)区域性中,然后向
DateTime.Parse()方法提供适当的CultureInfo
。这似乎不再是一个选项,因为您无法控制存储日期
你必须看看你是否能弄清楚它是如何存储日期的,并采取相应的行动。检查俄罗斯系统上的操作系统设置;也许有人改变了默认值,数据库也相应地做出了反应?如果是这样的话,你可能会以同样的方式做出反应
否则,您需要在系统和日期存储方式之间建立某种关联。如果所有俄罗斯系统都以相同的方式存储它,您可以打开当前区域性并使用ParseExact
。虽然感觉有点像黑客,但我不确定您是否还有其他选择。坦率地说,您需要:
- 了解数据库中的预期格式。如果可能的话,将其设置为字符串形式的单一标准格式,或者最好是数据库中的日期/时间类型(然后可以将其作为
DateTime
从数据库中读取,而无需代码执行任何转换)
- 通过调用
DateTime.ParseExact
并显式指定格式字符串,使用所需的格式
在数据库中,如果必须将其存储为文本,则应标准化格式。不过,更好的是,将其存储为datetime
,并且没有什么需要解析的内容—只需将其作为日期从数据库中读取即可
如果您有字符串,请在解析时使用已知区域性(可能是不变区域性):
DateTime when = DateTime.Parse(s, CultureInfo.InvariantCulture);
听起来您的问题似乎出在与数据库的连接上
在windows上,您应该:
-检查数据源的区域设置,
-您的数据连接字符串,
-或者更改RDBMS上用户的默认语言
每一项都可以确保以正确的格式返回数据
当然,解决方案的具体细节取决于您所使用的数据库和操作系统。您好。数据库中存储日期的“产品”不是“我们的”,因此我们不能对其进行任何修改。同意。不幸的是,有时没有好的/可行的解决方法,序列化选项值就是一个例子……而遗留产品或互操作性则是另一个例子(你好,Jon,谢谢你的回复。-在DateTime.ParseExact中,是否有方法将其指定为DateTime.ParseExact(dateString,“MMDDYYYY hh:mm:ss”),其中*是通配符?根据我们的分析,“产品”只写入数据库“尊重”日期分隔符,而不是日期格式。格式始终为MM DD YYYY,分隔符取决于计算机的区域设置。我不知道。如果存在大量潜在的格式字符串,您可以使用ParseExact重载指定所有这些字符串,该重载接受一组格式字符串。或者清除数据以:创建一个Str开始ingBuilder使用原始字符串,用已知字符在特定位置上跺脚,然后使用该字符进行解析。或者自己解析:)您可以使用DateTime.ParseExact(dateString.replace(“.”,“/”,“MM/DD/YYYY hh:MM:ss”)。我建议在公共方法中执行此逻辑,以便您以后可以对其进行细化并在整个项目中使用。根据我们的分析,它总是将日期存储为MM DD YYYY。然后获取机器区域设置的分隔符。例如,在美国,格式是MM/DD/YYYY,而在俄语中格式是MM.DD.YYYY。然后,您可能可以使用String.Replace(“.”,“/”)来替换它。只要保持警惕,以确保它不会在不久的将来随时中断。。。