【问题标题】:DateTime.Compare method is not working with different languagesDateTime.Compare 方法不适用于不同的语言
【发布时间】:2013-05-30 23:06:44
【问题描述】:

我需要比较我的 DotNetNuke 模块中的两个 DateTime 值,如下所示:

// This value actually comes from the database.
DateTime time1 = Convert.ToDateTime("6/2/2013 5:21:05 PM");

// Say it is now "5/31/2013 2:20:33 AM"
DateTime now = DateTime.Now;

int num = DateTime.Compare(time1, now);

如您所见,num == 1 因为time1DateTime 值大于nowDateTime 值。但是当我在 DotNetNuke 设置中将语言更改为德语 (de-DE) 时,now 的值变为 - 31/5/2013 2:20:33 AM。结果是num 变为-1,这意味着time1now 早于。这是不正确的,因为time1 实际上晚于now

time1 值始终采用mm/dd/yyyy 格式,因为它来自服务器。

那么,如果在 DotNetNuke 中设置了另一种语言,我该如何进行正确的比较?上网一搜,发现可以用下面的代码更正时间:

provider = new CultureInfo("en-US");
DateTime.ParseExact("5/31/2013", "d", provider);

正确吗?有没有更好的方法来处理这个问题?

编辑

忘了说时间 1 在保存到数据库之前来自我的网站服务器,并与现在变量中客户网站的日期时间值进行比较。所有代码都是我在该客户端站点中的应用程序。这些代码首先访问 time1 日期.net 获取远程站点数据的方法。所以当 dnn 站点语言设置为 de-DE 时,“现在”变量值是第一天,这与我的站点日期相反,日期是美国格式月份第一。因此,当进行比较时,我的服务器日期早于客户站点日期!一切都中断了。仅供参考,我的服务器日期是 i 周后的日期,即 6 月 2 日,用于许可目的。

再次编辑:

嗨every1。我通过以下代码找到了解决方案。正如我上面所说,这个日期来自我的另一台服务器 - “6/15/2013”​​(更改它是bef4 6/2/2013)。它是字符串格式,为什么它是一个字符串?这是一个悠久的历史。现在让它成为一个字符串。在转换为字符串之前它是美国日期格式(前一个月)。现在在我的应用程序所在的当前网站中,这些代码似乎工作。希望我没有错,拜托确认

CultureInfo provider = CultureInfo.InvariantCulture;
provider = new CultureInfo("en-US");
DateTime time1 = DateTime.ParseExact("6/15/2013", "d", provider);                    
DateTime now = DateTime.Now;
int num = DateTime.Compare(time1, now);

"num" 返回 1,无论 dnn 站点语言是德语还是英语,都是正确的。

【问题讨论】:

  • 您找到的解决方案是正确的Link 如果您进行了转换,则文化信息是必要的。我认为是一个好方法,但我不知道这是否是好的做法。
  • 我看到你对 StackOverflow 比较陌生。欢迎!但请尝试在未来做得更好,使用正确的格式和语言提出问题。此外,这个特定问题之前已经被问过 很多次 次,只是方式略有不同。请参阅herehere 和其他几个(太多无法列出)。但由于我找不到exact重复,我也会在下面回答。

标签: c# asp.net .net datetime dotnetnuke


【解决方案1】:

正如您所指出的,当日期由字符串表示时,我们处理日期的方式存在文化差异。 DD/MM/YYYY 格式在欧洲大部分地区和世界其他地区很常见,而 MM/DD/YYYY 几乎只由美国使用(有少数例外)。还有很多其他格式。

您应该知道一种重要格式,即ISO8601 标准。您通常可以将此视为时间戳,例如 2013-05-31T02:20:33。有时会包含尾随 Z 以指示时间为 UTC。您可能还会看到一个偏移量,例如 -07:00 或只是 -0700。这都是同一标准的一部分。最常见的用法也在RFC3339 中表示。每当您实际需要将DateTime 作为字符串发送时,您可能应该使用这种格式。 (向用户显示字符串以及收集用户输入时例外。)

现在,您应该了解DateTime 不是 字符串值。它在内部由一个 64 位整数表示。它不会在内部保留 任何 格式或文化设置。 DateTimestring 之间的转换只能用于输入和输出目的。通常这是在您的用户界面中,或者对于 ASP.Net,它可以在您的网页上。

在您使用DateTime 的任何其他地方,您根本不应该处理字符串。尤其是在比较值时。让我们剖析您的代码。首先我们有这行:

DateTime time1 = Convert.ToDateTime("6/2/2013 5:21:05 PM");

现在你说它是从数据库中出来的,但如果是这种情况,那么你不应该有一个字符串。假设您使用的是 SQL Server 数据库(但同样的概念也适用于其他数据库),并且数据位于 DateTime 类型的列中。当您从数据访问层检索值时,它应该作为纯 DateTime 从 SQL 流向 .Net。不涉及字符串。假设您使用的是 ADO.Net,并且您有一个DataReader。您应该将值加载为:

DateTime time1 = (DateTime)reader["columnname"];  // good

如果你正在做这样的事情:

DateTime time1 = Convert.ToDateTime(reader["columnname"].ToString());  // bad!

然后您将文化信息引入到您用作中间步骤的字符串中。这可能是您的问题的根源。不需要时不要使用字符串。

另外,我会完全避免使用Convert.ToDateTime。如果你确实需要解析一个字符串,你应该使用DateTime.Parse,如果你已经知道该字符串的确切格式,那么你应该使用DateTime.ParseExact

您的代码的下一行是:

DateTime now = DateTime.Now;

为此,您应该了解您从服务器上的时钟获取本地时间。这可能不是您网站用户的时间。而且由于您将其与数据库值进行比较,这意味着您也将本地时间存储在数据库中。这可能会带来很大的问题,因为服务器可能具有特定的时区设置。此外,如果时区发生夏令时(也称为夏令时)的更改,则有些值不存在,有些值存在 两次。这可能会导致重大问题,尤其是在比较这些值时。更好的方法是使用DateTime.UtcNow,或者使用DateTimeOffset 类型而不是DateTime 类型。您可以阅读更多相关信息,here

最后一行:

int num = DateTime.Compare(time1, now);

这很好,但您可能会发现使用常规布尔比较更容易,例如:

if (time1 >= now) ...

那么如何处理文化问题呢?解析用户输入时,请执行以下操作:

// Use the culture setting of your user.  Perhaps DNN has this already.
CultureInfo provider = new CultureInfo("de-DE");

// Parse the input string, but let the provider do the work to know the format.
DateTime dt = DateTime.Parse("31/5/2013", provider);

// Send data back to the user with the same provider.
string s = dt.ToString("d", provider);

您可能更喜欢使用TryParse 方法,以防您的用户提供错误数据:

DateTime dt;
if (!DateTime.TryParse(s, provider, DateTimeStyles.None, out dt)
{
    // handle invalid data
}

最后,你应该熟悉DateTime.Kind,并了解LocalUtcUnspecified三种类型的区别。如果您发现需要在应用程序中处理其他时区,那么您可能还需要了解 TimeZoneInfo 类。

【讨论】:

  • 嗨,我的问题还没有解决!如您在此示例中看到的,我使用“5/31/2013”​​作为示例。实际上,在 parseexact 方法中,我想将 datetime.now 值转换为美国日期格式(首先是月份)然后我可以将 time1 日期与 now 变量中的日期进行比较,无论当前站点 url 是 de-DE 还是 en-US。正如您所看到的,当语言是 de-DE 时,它会返回错误的值“-1”。请帮助任何人尽快
  • 不,你倒退了。将DateTime.Now 保留为DateTime。如果time1 也是DateTime,那么您没有格式或语言问题。您需要更加关注如何将time1 转换为DateTime
  • 是的,正如您在代码中看到的那样,time1 来自我的服务器,正如我所说的编辑 Q.first 那个日期我转换为 datetime 并保存在 time1.so 阅读我的问题,谁能给我工作代码无论站点语言设置为德语还是英语,哪个比较结果表明 time1 现在高于 date?
  • 请停下来试着理解我在告诉你的内容。唯一受站点语言影响的是DateTime 值是如何从字符串 解析的。如果你从不处理字符串,那么你就不会有这个问题。你说你有问题,所以你一定是从某个地方的字符串中得到time1,你不应该那样做!
  • 再次更新您的问题,并显示time1 实际源自的代码 - 而不是编造的示例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-18
  • 2021-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多