C# 不同服务器上服务器的全局区域性不同时的日期时间问题

C# 不同服务器上服务器的全局区域性不同时的日期时间问题,c#,asp.net,sql,datetime-format,C#,Asp.net,Sql,Datetime Format,我的网站位于不同位置的多台服务器上 数据格式的区域性在任何地方都是不同的-我们在任何地方都使用mm/dd/yyyy格式,但如果某些服务器将区域性设置为dd/mm/yyyy,则我们的网站会生成Datetime异常。从不依赖服务器的默认区域设置。对于您的情况,这意味着: 在将日期作为(未格式化的)日期对象传递而不是作为(格式化的)字符串对象传递时,请使用准备好的语句。无论如何,您都不应该在应用程序中使用字符串来表示日期,因为您无法对它们执行特定于日期的函数(例如添加1个月、获取当前一周的最后一天等

我的网站位于不同位置的多台服务器上

数据格式的区域性在任何地方都是不同的-我们在任何地方都使用
mm/dd/yyyy
格式,但如果某些服务器将区域性设置为
dd/mm/yyyy
,则我们的网站会生成Datetime异常。

从不依赖服务器的默认区域设置。对于您的情况,这意味着:

  • 在将日期作为(未格式化的)日期对象传递而不是作为(格式化的)字符串对象传递时,请使用准备好的语句。无论如何,您都不应该在应用程序中使用字符串来表示日期,因为您无法对它们执行特定于日期的函数(例如添加1个月、获取当前一周的最后一天等)

  • 如果您确实需要在应用程序中使用字符串对象,请在任何地方使用SQL函数,如
    to_date
    to_char
    (确切名称取决于您的DBMS)


永远不要将日期作为字符串存储在内部。不在数据库中,也不在应用程序中

如果需要在服务器之间移动日期值,请使用二进制。或者,如果确实需要使用字符串,请使用
ToString(CultureInfo.InvariantCulture)
——或者简单地序列化
Ticks
属性


另外,永远不要使用使用代码生成的SQL命令将日期作为字符串传递给数据库。使用
SqlParameter
实现这一点,或者更好地依赖于一些O/R映射程序,例如实体框架或Linq到SQL。

如果部署到不受您控制的服务器上,则确保您的代码对区域性没有硬编码的依赖关系是至关重要的


您很可能希望在代码中搜索DateTime.Parse或类似内容。我们在
DateTime
上有一组扩展方法,用于强制使用正确的区域性。

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

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

String s = "24. 10. 2011";
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
然后您需要解析字符串,就好像它是在斯洛伐克(斯洛伐克)
sk-sk
)文化中一样:

如果您的日期都在塔吉克语(塔吉克斯坦西里尔文),则需要将其解析为
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-AU
    (澳大利亚英语):
    24/10/2011
  • en IA
    (英语印度):
    24-10-2011
  • Enza
    (南非英语):
    2011/10/24
  • en-US
    (英语美国):
    10/24/2011
我想你更喜欢英语(印度)(
en IA


但是,如果在将日期转换为字符串(反之亦然)时确实无法决定要使用哪种区域性,并且日期永远不会显示给用户,则可以使用不变区域性:

String s = "24. 10. 2011";
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

简单易懂的解决方案非常感谢,但Ian Boyd已经解释了为什么我们应该进行这种解析。感谢你们两位。感谢那个因为“很难说出这里有什么问题”而投票关闭的人:什么让你们困惑?你们永远不应该使用域或操作系统中的任何区域性设置。如果任何人出于任何原因(如其他应用程序无法正常工作)覆盖这些,您的应用程序将停止工作。如果格式始终相同,则应使用tryparseexact或parseexact。对于所有这些,在windows 10上,默认的sk date格式不带空格。