Bug 6220 - DateTime MinValue implicit comparison to DateTimeOffset Throws Error in European Time Zones
Summary: DateTime MinValue implicit comparison to DateTimeOffset Throws Error in Europ...
Status: RESOLVED NOT_ON_ROADMAP
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: 5.3.x
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2012-07-20 16:59 UTC by blake
Modified: 2012-07-23 12:12 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED NOT_ON_ROADMAP

Description blake 2012-07-20 16:59:21 UTC
When an iPhone is set to European time zones (or possibly anything with a positive utc offset), an implicit comparison between a DateTime that is MinValue and a DateTimeOffset that is in another timezone will cause a crash.


Stacktrace:

System.ArgumentOutOfRangeException: Argument is out of range.
  at System.DateTime.op_Subtraction (DateTime d, TimeSpan t) [0x00031] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/DateTime.cs:2050 
  at System.DateTimeOffset.get_UtcDateTime () [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/DateTimeOffset.cs:862 
  at System.DateTimeOffset..ctor (DateTime dateTime) [0x00035] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/DateTimeOffset.cs:65 
  at System.DateTimeOffset.op_Implicit (DateTime dateTime) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/DateTimeOffset.cs:258
Comment 1 Rolf Bjarne Kvinge [MSFT] 2012-07-20 18:44:56 UTC
What do you suggest should happen?

You can't get anything meaningful from "MinValue - X", a DateTime struct can't describe it.
Comment 2 blake 2012-07-20 18:54:19 UTC
Well, it's kind of a weird scenario because all the code is doing is saying is date time A < datetimeoffset B.  A happens to be an uninitialized datetime, and B is a DateTimeOffset in eastern time.  Somehow the coercion to UTC and comparison is triggering the error.  It works fine in EST, just not in CET.  I think this case shouldn't crash the device, for sure.  As to what the underlying code should do, maybe anything less than 0 ticks should just be reset to 0 ticks?
Comment 3 Sebastien Pouliot 2012-07-23 10:48:17 UTC
MS .NET fails with the same exception (even if the check is not done at the same place and a different, if not more useful, message is provided). 

TestCase 'mcs_unit_tests.zlass1.XX'
failed: System.ArgumentOutOfRangeException : The UTC time represented when the offset is applied must be between year 0 and 10,000.
Parameter name: offset
	at System.DateTimeOffset.ValidateDate(DateTime dateTime, TimeSpan offset)
	at System.DateTimeOffset..ctor(DateTime dateTime)
	at System.DateTimeOffset.op_Implicit(DateTime dateTime)
	zlass1.cs(50,0): at mcs_unit_tests.zlass1.XX()

Changing this behavior (in Mono/MonoTouch) would introduce incompatibilities. Catching the exception around your date computations is the best solution (for this and potentially other corner cases).
Comment 4 blake 2012-07-23 10:58:35 UTC
Sorry, but that's not true.  You guys seem hung up on the subtraction, but I think it's just because that's how you've implemented the date comparison.  I've NEVER had a date comparison throw an exception.  You're telling me that you can get this to fail:

Change your time zone to CET.

public DateTime LastModified {get;set;}

public void Test(DTO Details){
   if (Details.LastModified < LastModified) {
  -- do something
}//fails with exception (details.lastmodified is an initialized DateTimeOffset in timezone A, LastModified is NOT initialized, so becomes a local datetime)
}
Comment 5 Sebastien Pouliot 2012-07-23 11:47:17 UTC
The stack trace I added in comment #3 comes from:
* Microsoft .NET v4.0 
* Windows 7
* CET time zone (+1)

The code executed is:

			DateTime uninit = DateTime.MinValue; // csc won't let you use an uninit var
			DateTimeOffset est = new DateTimeOffset (DateTime.UtcNow.Ticks, TimeSpan.FromHours (5));
			if (uninit < est)
				Console.WriteLine ();

and it throws an System.ArgumentOutOfRangeException on the comparison line. There's no *substruction* involved in the test case.

If you have a self-contained specific test case, with values, that can be copy-pasted and executed and shows a different behavior between Mono and MS.NET please attach it to the bug report.
Comment 6 blake 2012-07-23 12:03:10 UTC
Ok, I'm wrong.  I agree with you.  It seems like a very odd choice to throw exceptions in the comparison case, but it does appear to match the .NET behavior (e.g.: http://stackoverflow.com/questions/6924198/converting-datetime-minvalue-to-datetimeoffset).

I suppose we've never seen this because the server side code all runs in UTC, so we don't have this cause ever come up.
Comment 7 Sebastien Pouliot 2012-07-23 12:12:19 UTC
I was surprised too, enough to boot up a Win VM ;-)