asp.net datetime 随机复制时间偏移。是一个错误?

Posted

技术标签:

【中文标题】asp.net datetime 随机复制时间偏移。是一个错误?【英文标题】:asp.net datetime randomly duplicate time offset. is a bug? 【发布时间】:2015-12-29 07:13:31 【问题描述】:

我有一个用 asp.net 4 和 sql server 2008 R2 开发的网站。 问题非常复杂。 我在 db 中有一个数据时间偏移 UTC 的字段(例如 2015-09-30 18:24:53.1498113 +02:00)。 随机(我认为当应用程序池重新启动时)这个值在.net中查询后返回损坏,如下所示: 2015 年 9 月 30 日 18:21:00 +02:00 +02:00 时间偏移重复了 2 次!

所以,当我在 c# 中解析日期时,显然我收到一个错误“字符串未被识别为有效的 DateTime”。

如果我回收池应用程序页面工作正常

为什么?这是一个错误?你见过类似的问题吗?

非常感谢

【问题讨论】:

看起来像是在粘贴字符串,但您没有给我们足够的信息。 嗨,Ben,很难替换这个问题,因为它是随机发生的,并且在网站存在的 6 个月内只有 3 次。 当应用程序池重新启动时(我认为)从 db 读取的 utc 日期是错误的。 Web 服务器有意大利语的全球化设置,还有 web.config 中的网站。只有一次在当地我已经更换了这种情况。并使用 Visual Studio 调试我看到了这个问题。数据集中的日期错误(例如 09/09/2015 +02:00 +02:00)。我认为这是一个错误,因为如果我回收应用程序池,网站可以正常工作...... DateTimeOffset 在 SQL Server 或 .NET 中都没有损坏。似乎数据库已损坏并且存储了一个字符串而不是正确的类型datetimeoffset。看起来一些错误的数据访问代码正在附加另一个偏移字符串。唯一真正的解决方案是修复数据库并摆脱所有解析代码 您很可能有剩余代码试图将偏移量附加到仅日期时间的字符串。这与 .NET 或数据库无关,因此只有您可以找到错误代码。 【参考方案1】:

我们在 IIS 上托管的 asp.net-mvc 应用程序 (.NET 4.5) 中观察到了相同的行为。在这个看似无害的代码中,当从 razor cshtml 中的模型序列化 DateTimeOffset 值时,其中一台服务器开始生成重复的偏移量(数周内没有部署任何版本):

@Html.HiddenFor(m => m.CreateDate)
<span>@Model.CreateDate</span>

在这两个地方都生成了重复的偏移量,例如 2017-11-20 12:34 +01:00 +01:00。 重新启动 IIS 池解决了这个问题,但我不知道以后如何避免它。

【讨论】:

【参考方案2】:

这是由 DateTimeOffset 的 ToString() 方法中的竞争条件引起的。竞争是因为代码在构建模式字符串时直接针对 dateTimeOffsetPattern 成员工作。模式字符串是短日期模式和长时间模式的串联。一些文化在长时间模式中包含偏移量,因此代码会对此进行检查。在字符串中不包含偏移量的情况下,它会像这样连接偏移量格式:

if (!foundZ) 
    dateTimeOffsetPattern = dateTimeOffsetPattern + " zzz";

根据执行顺序,有时会执行两次或在一个线程中执行而不在另一个线程中执行。

此问题已在较新版本的 .Net Framework 中得到修复,但可以通过提供您自己的格式字符串来解决。

【讨论】:

看起来它在 .Net Core 中已修复,但在框架中没有:github.com/dotnet/coreclr/issues/2301 github.com/microsoft/dotnet/issues/1144 感谢@Rob 的解释! bug 仍然存在于 .net 4.7.2【参考方案3】:

在我们的一项 WCF 服务中观察到类似的行为 - 我们的具体情况是使用 Newtonsoft.Json 从传入请求反序列化的 DateTimeOffset 值正在使用 DateTimeOffset.ToString() 转换为字符串,我们最终得到的字符串表示形式如下所示

MM/dd/yyyy 12:00:00 AM -04:00 -04:00

我们的第一个假设显然是这是我们代码中的错误 - 它始终是您的代码,对吗?但是,我们最终非常详尽地跟踪了执行,找不到任何可能的方式我们自己会导致这个问题 - 很难相信,似乎DateTimeOffset.ToString 的结果真的只是返回那个字符串格式在服务器上。

导致错误的特定字符串转换发生在内部框架中,因此我们只是换掉了转换方式,以便我们现在使用显式字符串格式。尚无确认是否有效。我们的替换实现如下所示 -

offset.ToString("MM/dd/yyyy HH:mm:ss tt zzzz");

我们的短期解决方案是重新启动 IIS 应用程序池 - 在我们遇到两次之后,该问题立即停止出现。

【讨论】:

这最终解决了您的问题吗?我刚刚推出它,我会密切关注它。 自我们部署此更新以来,我们再也没有发生过这种情况,因此它似乎已修复,但同时它是如此间歇性和罕见的问题,很难说 - 我们有一个非常大量使用的 API 并且已经使用了将近一年,但我们甚至花了几年的时间才开始遇到这个问题。很难确定。【参考方案4】:

编辑:请参阅 Rob 的解决方案;这是一个框架错误。

旧:

今天我们也遇到了这种情况 - 我第一次看到它。这绝对不是亚历克斯的错误,它是一个强类型的 DateTimeOffset 与沼泽标准 .ToString() 添加偏移量两次。它只发生在我们的一个网络服务器上,我希望如果我们踢它它会消失。我敢肯定,明确地为 ToString 提供字符串格式会防止它再次发生,并且这里可能会发生某种操作系统级别的损坏,因为我已经看到默认格式随着操作系统升级而发生变化(在这种情况下它可能会不会)当我们踢它时不会固定)。

【讨论】:

今天发生在我们身上。这个线程是我能找到其他人见过这个的唯一证据。我们在 DateTimeOffset 上调用 .ToString() 并得到“4/4/2019 12:00:00 AM -05:00 -05:00”,直到我们重新启动应用程序池并且它停止发生。我们能想到的唯一解释是微软这边有一个错误。【参考方案5】:

当我们尝试解析使用 DateTimeOffset.toString() 值转换的字符串时,发生了同样的问题。 ADO.Net 客户端转换中的 DateTimeOffset.toString() 返回无效的 DateTimeOffset 格式,并带有重复的 Offset 值。我们停止了 DateTimeOffset 的字符串转换,直接开始使用 DateTimeOffset 对象。

【讨论】:

您有两个错误 - 使用错误的类型存储 DateTimeOffset 值和错误的解析代码。在这种情况下,唯一合乎逻辑的解决方法是将列的类型更改为 DateTimeOffset。 PS ToString() formats,它不解析任何东西,它没有损坏 在 Vertica DB 中,我们使用与 DateTimeOffset 相同的列类型 (TIMESTAMPTZ) 来存储时间和时区偏移量。我们尝试使用 ToString() 方法将 db 检索到的值转换为字符串。 ToString() 的返回值与其中重复的 Offset 值不一致。因此,人们对 Vertica 的 ADO.Net 客户端产生了怀疑。我们无法找到发生这种情况的时间,因此无法确定确切的问题。 DateTimeOffset.ToString()String.Format 并不矛盾。如果偏移量出现两次,那是因为格式字符串包含两次偏移量说明符。它也很容易测试 - 只需创建一个 DateOffset 值并使用相同的格式字符串

以上是关于asp.net datetime 随机复制时间偏移。是一个错误?的主要内容,如果未能解决你的问题,请参考以下文章

asp.net 根据时间获取星期

ASP.NET RedirectToAction 更改请求中的 DateTime 格式

从 ajax 调用到 javascript 日期的 ASP.NET 解析 DateTime 结果

Asp.net 日期时间文化问题

更改 ASP.NET Core 中 DateTime 解析的默认格式

ASP.NET MVC Controller.Json DateTime 序列化与 NewtonSoft Json DateTime 序列化