Convert.ToDateTime 在下午的日期/时间值上导致 FormatException
我们有一个应用程序解析以下格式的日期/时间值:
2009-10-10 09:19:12.124
2009-10-10 12:13:14.852
2009-10-10 13:00:00
2009-10-10 15:23:32.022
一台特定服务器突然(今天)开始无法解析 13:00:00 或之后的任何时间。该特定客户端有五台服务器,只有一台出现问题。我们还有数十个其他客户端,总共数百台服务器都没有出现问题。
System.FormatException: String was not recognized as a valid DateTime.
at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles)
at System.DateTime.Parse(String s, IFormatProvider provider)
at System.Convert.ToDateTime(String value, IFormatProvider provider)
at System.String.System.IConvertible.ToDateTime(IFormatProvider provider)
at System.Convert.ToDateTime(Object value)
我使用 DateTime.Parse(s, CultureInfo.CurrentCulture) 与 DateTime.Parse(s, CultureInfo.InvariantCulture) 进行比较,进行了测试,问题仅出现在 CurrentCulture 中。然而,CurrentCulture 是“en-US”,就像所有其他服务器一样,我在区域或语言设置中找不到任何不同之处。
有人见过这个吗?与我可以研究的内容相关的建议?
编辑:感谢您到目前为止的回答。但是,我正在寻找有关要研究哪些配置的建议,这些配置可能会导致其行为突然改变并在运行多年并在数百台其他服务器上运行时停止工作。我已经在下一个版本中更改了它,但我正在寻找配置更改来在当前安装的过渡期间修复此问题。
We have an application parsing date/time values in the following format:
2009-10-10 09:19:12.124
2009-10-10 12:13:14.852
2009-10-10 13:00:00
2009-10-10 15:23:32.022
One particular server all of the sudden (today) started failing to parse any times 13:00:00 or later. This particular client has five servers and only one has the problem. We have dozens of other clients with a total of hundreds of servers without the problem.
System.FormatException: String was not recognized as a valid DateTime.
at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles)
at System.DateTime.Parse(String s, IFormatProvider provider)
at System.Convert.ToDateTime(String value, IFormatProvider provider)
at System.String.System.IConvertible.ToDateTime(IFormatProvider provider)
at System.Convert.ToDateTime(Object value)
I ran a test using DateTime.Parse(s, CultureInfo.CurrentCulture) comapred to DateTime.Parse(s, CultureInfo.InvariantCulture) and the problem only shows up with CurrentCulture. However, CurrentCulture is "en-US" just like all the other servers and there's nothing different that I can find in regional or language settings.
Has anyone seen this before? Suggestions related to what I can look into?
EDIT: Thank you for the answers so far. However, I'm looking for suggestions on what configuration to look into that could have caused this to suddenly change behavior and stop working when it's worked for years and works on hundreds of other servers. I've already changed it for the next version, but I'm looking for a configuration change to fix this in the interim for the current installation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
如果您确切地知道格式,请告诉应用程序它是什么 - 使用
DateTime.ParseExact
而不仅仅是DateTime.Parse
。 (正如其他人所说,还要指定不变的区域性,以消除更多的变化。)这给了你更多的控制权:If you know the format exactly, tell the application what it is - use
DateTime.ParseExact
instead of justDateTime.Parse
. (And as others have said, specify the invariant culture as well, to take away any more variation.) That gives you much more control:我们也遇到了同样的问题。只需回收您的应用程序池即可。
We also encountered the same problem. Just recycle your application pool.
我们有一个在 Windows 2003 服务器上运行的 C# .NET 2.0 Web 服务。该服务已经运行了两年多。我们最近开始在该应用程序中遇到错误。错误消息是“字符串未被识别为有效的日期时间”。另一个网络服务返回一个日期,该函数应该返回一个类似的值
当发生错误时函数返回
错误的返回末尾有空格且没有 AM。
在接下来的几周内,这个问题多次出现又消失。检查 Windows 日志后,我们注意到错误的开始和结束时间与设置(默认情况下)每 29 小时发生一次的应用程序池回收时间一致(在一两分钟内)。此问题仅出现在生产 Web 服务器上,而不会出现在开发或测试服务器上。我们尝试更换服务器,一个月没有出现任何错误。现在错误又开始了。我们手动重置池,问题立即消失。我们不希望将此视为可接受的解决方案,因为池会定期回收。我们不知道是否需要池回收,但我们的理解是定期回收有助于提高应用程序性能。
Web 应用程序已经使用 ParseExact(),但格式字符串如下所示:
而不是
Jon Skeet 在此线程中建议 。我不知道这是否会产生很大的影响。
我们还检查了文化设置。
很明显,问题始于应用程序池回收,但我不知道回收期间幕后发生了什么。大多数情况下,回收不会产生负面影响,并且当错误确实发生时,下一次回收总是会停止错误。
We have an C# .NET 2.0 web service running on a Windows 2003 server. That service has been running for more than two years. We recently srtarted experiencing errors in that application. The error message is "String was not recognized as a valid DateTime". Another web servie returns a date, and that function should return a value like
When the errors are occurring the function returns
The incorrect return has white space at the end and no AM.
This problem appeared and disappeared several times over the next couple of weeks. After examining the windows logs, we noticed that the start and end times of the errors coincided (within a minute or two) of an application pool recycle that is set (by default) to occur every 29 hours. This problem only occurred on the production web server, and not on the development or test servers. We tried replacing the server, and there were no errors for a month. Now the errors have started again. We manually reset the pool and the problem disappeared immediately. We would rather not view this as an acceptable solution, as the pool recycles regularly. We don't know if we need the pool recycle, but it is our understanding that regular recycles help with application performance.
The web application uses ParseExact() already, but the format string looks like this:
instead of
suggested by Jon Skeet in this thread. I don't know if this would make much difference.
We also checked the culture settings.
It seems clear that the problem begins with the application pool recycle, but I have no idea what occurs under the hood during that recycle. Most of the time the recycle has no negative effect, and when the errors do occur, the next recycle has always stopped the errors.
解决方案非常简单,使用
CultureInfo.InvariantCulture
。对于样本数据,这是唯一明智的做法。我知道这并不能解释其中的差异,但你的软件确实不应该依赖于“默认”文化(也许在用户界面中除外)。
The solution is very simple, use
CultureInfo.InvariantCulture
. For the sample data that is the only sensible thing to do.I know this doesn't explain the difference, but your software really shouldn't rely on the 'default' culture (except maybe in the UI).
我刚刚找到了一些有关导致此问题的原因的信息。我们的 C# 客户端将业务日期(仅日期)作为字符串值发送到 Web 服务。 Web 服务将 SqlParameter 中的此字符串传递给 SqlCommand 以及接受业务日期的
datetime
参数的存储过程。客户的系统突然出现异常。我使用 SQL Server Profiler 观察 RPC 调用,并注意到日期参数突然包含了时间部分。这应该是仅日期值 - 即 10/27/2012 12:00:00 AM。
我修改了存储过程以添加
WAITFOR DELAY '00:01:00'
。然后,当 Web 服务调用该存储过程时,我获取了该 Web 服务的内存转储。检查内存转储,我发现客户端在参数数据集中传入了正确的日期字符串“2012-10-25 00:00:00”。 Web 服务在调用存储过程时以某种方式搞乱了这些日期的转换。我在转储中找到了 SqlCommand,并检查了与存储过程的日期参数相对应的 SqlParameter。该值为“10/25/2012 12:00:00 PM”。
查看所有 CultureInfo 对象,我发现“en-US”的区域设置 1033 有一个很长的字符串“h:mm:ss tt”。 AMDesignator 是“AM”,但是PMDesignator 是一个空字符串!我通过运行以下命令验证了这是 C# 中错误日期的原因:
结果是“10/25/2012 12:00:00”,这与 Brian Begley 的答案相对应。使用不变格式会产生非常相似的结果:
我尚未确定导致 CultureInfo 损坏的原因。
请注意,Microsoft 已意识到此问题。链接的文章说它仅适用于 Windows Server 2003,并且有一个可用的修补程序。
I've just found some information about what is causing this issue. Our C# client sends a business date (date only) as a string value to a web service. The web service passes this string in a SqlParameter to a SqlCommand to a stored procedure that accepts a
datetime
parameter for the business date.A customer's system was suddenly misbehaving. I used the SQL Server Profiler to watch the RPC calls and noticed that the date parameter suddenly had a time component. This is supposed to be a date only value-- i.e. 10/27/2012 12:00:00 AM.
I modified the stored procedure to add a
WAITFOR DELAY '00:01:00'
. I then acquired a memory dump of the web service while it was making the call to this stored procedure.Examining the memory dump, I found that the client had passed in the correct date string of "2012-10-25 00:00:00" in a DataSet of parameters. The web service somehow messed up the conversion of these dates when it called the stored procedure. I found the SqlCommand in the dump and examined the SqlParameter corresponding to the stored procedure's date parameter. The value was "10/25/2012 12:00:00 PM".
Looking at all the CultureInfo objects, I found locale 1033 for "en-US" had a long time string of "h:mm:ss tt". The AMDesignator was "AM", but the PMDesignator was an empty string! I verified this was the cause of the bad date in C# by running the following command:
The result was "10/25/2012 12:00:00 " which corresponds to what Brian Begley in his answer. Using the invariant format yields a very similar result:
I have yet to determine what is causing the CultureInfo to be corrupted.
Note that Microsoft is aware of this issue. The article linked says it applies only to Windows Server 2003, and there is a hotfix available.
听起来好像文化对象不理解军事时间符号。老实说,我不确定从哪里开始,但它可能会给你一个起点。
It sounds like somehow the culture object isn't understanding military time notation. I'm honestly not sure where to go from there, but it may give you a starting point.
CultureInfo.DateTimeFormat
属性的值是多少? 根据 MSDN:可能是某些用户设置覆盖了这一点?
What's the value of the
CultureInfo.DateTimeFormat
property? According to MSDN:Could it be some user setting is over-riding this?
这是一个疯狂的猜测,但也许像这样的事件序列可能导致了问题:
回收的服务器上的所有新 ASP.NET 工作线程现在都将看到更改后的时间格式,并且它们的
DateTime.Parse
方法将失败。但是,如果其他服务器仍在使用原始工作线程,则它们尚未检测到当前区域性DateTimeFormatInfo
的更改。这是一种非常不可能的情况,但话又说回来,你遇到了一种非常不可能的情况。您可以尝试回收所有服务器上的相关应用程序池,看看是否有任何变化。
It's a wild guess, but maybe something like this sequence of events might have caused the problem:
All new ASP.NET worker threads on the recycled server will now see the changed time format and their
DateTime.Parse
methods will fail. However, if the other servers are still using the original worker threads, then they have not yet detected the changes to the current cultureDateTimeFormatInfo
.It's a very unlikely scenario, but then again, you have a very unlikely situation. You could try recycling the relevant application pool on all the servers and see if anything changes.