【问题标题】:DateTime issue when global culture of the server is different on different servers当服务器的全球文化在不同服务器上不同时的日期时间问题
【发布时间】:2011-10-24 11:23:36
【问题描述】:

我的网站托管在不同位置的多台服务器上

数据格式的文化在每个地方都不同——我们在每个地方都使用mm/dd/yyyy 格式,但如果某些服务器将文化设置为dd/mm/yyyy,那么我们的网站会生成日期时间异常。

【问题讨论】:

  • 致因为“很难说出这里要问什么”而投票决定关闭的人:什么让你感到困惑?

标签: c# asp.net sql datetime-format


【解决方案1】:

您应该在将字符串转换为日期时指定要使用的文化。

您应该使用的文化取决于日期格式的文化。例如,如果您正在解析的所有日期都格式化为 斯洛伐克语

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-AU(澳大利亚英语):24/10/2011
  • en-IA(英语印度):24-10-2011
  • en-ZA(英语南非):2011/10/24
  • en-US(美国英语):10/24/2011

我怀疑你更喜欢英语(印度) (en-IA)。


但是,如果您真的无法决定在将日期转换为字符串时使用什么文化,反之亦然,并且日期绝不会显示给用户,那么您可以使用 Invariant Culture强>:

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

【讨论】:

  • 您不应该使用来自域或操作系统的任何文化设置。如果有人出于任何原因覆盖这些(例如其他应用程序无法正常工作),您的应用程序将停止工作。如果格式始终相同,则应使用 tryparseexact 或 parseexact。
  • 至于这一切,在windows 10上是新的默认sk日期格式,没有空格。
【解决方案2】:

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

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

此外,切勿使用您使用代码构建的 SQL 命令将日期作为字符串传递给数据库。为此使用SqlParameter,或者甚至更好地依赖一些O/R Mapper,例如Entity Framework 或Linq to SQL。

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

      从不依赖服务器的默认语言环境。对于您的情况,这意味着:

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

      • 如果你真的需要在你的应用程序中使用字符串对象

      【讨论】:

      • 感谢简单易懂的解决方案,但 Ian Boyd 已经解释了为什么我们应该处理这个解析。谢谢你们俩。
      猜你喜欢
      • 2015-07-28
      • 2014-12-12
      • 2015-09-01
      • 1970-01-01
      • 2019-02-19
      • 1970-01-01
      • 2013-07-13
      • 2023-03-14
      • 1970-01-01
      相关资源
      最近更新 更多