9

i have a website developed in asp.net 4 and sql server 2008 R2. The problem is very complicated. I have a field in db with datatime offset UTC (ex. 2015-09-30 18:24:53.1498113 +02:00). Randomly (i think when application pool restart) this value return corrupt after query in .net like this: 30/09/2015 18:21:00 +02:00 +02:00 Time offset repeated 2 times!

So, when i parse the date in c# obviously i receive an error "String was not recognized as a valid DateTime".

If i recycle pool applcation page work fine

Why? It's a bug? Have you ever seen similar problem?

Thanks a lot

alex
  • 101
  • 2
  • 1
    Looks like some string-pasting going on, but you haven't given us enough information. – Ben Oct 01 '15 at 09:34
  • Hi Ben, is very difficult replace the problem because it happens randomly and only 3 times in 6 months that the website exist. – alex Oct 02 '15 at 10:43
  • When the application pool restart (i think) the utc date read from db are wrong. The web server has globalization settings in italian, also the website in web.config. Only one time in local i have replaced the situation. And using visual studio debug i saw this problem. The date in dataset was wrong (ex 09/09/2015 +02:00 +02:00). I think is a bug because if i recycle app pool the website work fine... – alex Oct 02 '15 at 10:47
  • DateTimeOffset isn't broken either in SQL Server or .NET. It seems that the database is broken and a string is stored instead of the correct type, `datetimeoffset`. It also looks like some bad data access code is appending yet another offset string. The only *real* solution is to fix the database and get rid of all the parsing code – Panagiotis Kanavos Jul 04 '16 at 11:44
  • Most likely you have leftover code that tried to append an offset to a datetime-only string. This isn't related to .NET or the database, so only you can find the buggy code. – Panagiotis Kanavos Jul 04 '16 at 11:46
  • 1
    There is indeed a problem with DateTimeOffset. See @Rob 's answer and the following links: github.com/dotnet/coreclr/issues/2301 github.com/microsoft/dotnet/issues/1144 – K J Nov 26 '19 at 00:19
  • 1
    this is still a bug in .NET 4.7.2. This is a huge bug in the .NET framework. How can a bug like this not get addressed? I have to restart the app pool every time this occurs. – manit Jun 25 '20 at 15:26

5 Answers5

6

We observed the same behaviour in our asp.net-mvc application (.NET 4.5) hosted at IIS. One of the servers started to generate duplicated offsets (no versions were deployed for weeks) when serializing DateTimeOffset value from model in razor cshtml in this apparently harmless code:

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

In both places duplicated offsets were generated like 2017-11-20 12:34 +01:00 +01:00. Restarting IIS pool solved the problem, but I have no idea how to avoid it in the future.

PanJanek
  • 6,593
  • 2
  • 34
  • 41
4

This is being caused by a race condition in the ToString() method of DateTimeOffset. The race is caused because the code is directly working against the dateTimeOffsetPattern member when building the pattern string. The pattern string is the concatenation of the short date and long time patterns. Some cultures include the offset in the long time pattern, so the code checks for that. In the case where the offset is not included in the string, it concatenates the offset format like so:

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

Depending on execution order, sometimes this gets executed twice or executed in one thread and not in another.

This has since been fixed in newer versions of the .Net Framework, but can otherwise be worked around by providing your own format string.

Rob
  • 762
  • 2
  • 21
  • 44
  • Looks like it is fixed in .Net Core but not the Framework: https://github.com/dotnet/coreclr/issues/2301 https://github.com/microsoft/dotnet/issues/1144 Thanks for the explanation @Rob ! – K J Nov 26 '19 at 00:17
  • bug still exists in .net 4.7.2 – manit Jun 25 '20 at 15:31
2

Edit: See Rob's answer for the solution; it's a framework bug.

Old:

This happened to us too today - first time I've seen it. It's definitely not an error on Alex's part, it's a strongly typed DateTimeOffset with the bog standard .ToString() adding the offset twice. It's only happening on one of our web servers, and I expect it will go away if we kick it. I'm sure explicitly providing a string format for ToString would prevent it from recurring, and it's possible there's some kind of OS-level corruption happening here as I've seen the default formats change with OS upgrades (in which case maybe it won't get fixed when we kick it).

Drew Miller
  • 675
  • 6
  • 15
  • Happened to us today. This thread is the only evidence that I could find that anyone else has ever seen this. We were calling .ToString() on a DateTimeOffset and getting "4/4/2019 12:00:00 AM -05:00 -05:00" until we restarted the application pool and it stopped happening. The only explanation we can think of is that there's a bug on Microsoft's side. – Scott Baldwin Apr 04 '19 at 16:03
2

Observed similar behavior in one of our WCF services - our specific case is DateTimeOffset values deserialized from incoming requests using Newtonsoft.Json are getting converted to strings with DateTimeOffset.ToString() and we are ending up with string representations that look like this

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

Our first assumption was obviously that this was a bug in our code - its always your code, right? However, we traced execution pretty exhaustively on our end and couldn't find any possible way we would be causing this issue ourselves - as hard as it is to believe, it seems like the result of DateTimeOffset.ToString really is just returning that string format on the server.

The specific string conversion that's causing the error on our end is happening in an internal framework, so we're just swapping out the way we convert so that we're now using an explicit string format. No confirmation if that works or not yet. Our replacement implementation looks like this -

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

Our short term solution was to restart the IIS application pool - the issue immediately stopped exhibiting after this both times we encountered it.

Joshua Evensen
  • 1,544
  • 1
  • 15
  • 33
  • Did this end up fixing your issue? I'm just rolled it and I'm going to keep an eye on it. – GBreen12 May 28 '20 at 23:06
  • we haven't had this happen again since we deployed this update, so it seems fixed yes, but at the same time its so intermittent and rare as an issue it's hard to say - we have a very heavily used API and it's been ok for almost a year, but it took a few years for us to even run into this problem in the first place. tough to nail down. – Joshua Evensen Jun 15 '20 at 20:03
-1

The same issue happened when we were trying to parse the string converted using DateTimeOffset.toString() value. The DateTimeOffset.toString() in ADO.Net client conversion returns invalid DateTimeOffset format with duplicate Offset values. We stopped the string conversion of DateTimeOffset and started using the DateTimeOffset object directly.

  • You had two bugs - using the wrong type to store DateTimeOffset values and bad parsing code. The only logical fix in this case is to change the column's type to DateTimeOffset. PS `ToString()` *formats*, it doesn't parse anything and it *isn't* broken – Panagiotis Kanavos Jul 04 '16 at 11:42
  • In Vertica DB, we are using a column type([TIMESTAMPTZ](https://my.vertica.com/docs/7.1.x/HTML/index.htm#Authoring/SQLReferenceManual/DataTypes/Date-Time/TIMESTAMPATTIMEZONE.htm)) same as DateTimeOffset to store time along with timezone offset. We tried to convert the db retrieved value as string using ToString() method. The returned value of ToString() has been inconsistent with repeated Offset values in it. Hence the suspision around ADO.Net client for vertica. We were not able to find when this happens, hence not able to pin-point the exact issue. – Santhosh Kumar M Jul 08 '16 at 11:46
  • `DateTimeOffset.ToString()` or `String.Format` aren't inconsistent. If the offset appears twice, it's because the format string contains the offset specifier twice. It's easy to test too - just create a DateOffset value and use the same format string – Panagiotis Kanavos Jul 08 '16 at 12:07