Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does calling DateTime.AddDays with a whole number always leave the time unchanged?

Consider the following code which attempts to get a DateTime that's equivalent to the local time "midnight yesterday":

DateTime midnightYesterday = DateTime.Today.AddDays(-1.0d);

Will this always result in a DateTime with a time component of 00:00:00 -- regardless of any corner cases such as leap days, leap seconds, or what the local time zone is?

More generally: Does calling DateTime.AddDays, passing a whole number as a parameter, always result in a DateTime being returned that has the exact same time component as the original Datetime?

The MSDN documentation for DateTime.AddDays does not address this specific question.

like image 601
Jon Schneider Avatar asked Oct 20 '17 19:10

Jon Schneider


1 Answers

  1. DateTime does not account for leap seconds. You can read this article from which you will see that because of this it doesn't really support UTC. Documentation states that:

Time values are measured in 100-nanosecond units called ticks, and a particular date is the number of ticks since 12:00 midnight, January 1, 0001 A.D. (C.E.) in the GregorianCalendar calendar (excluding ticks that would be added by leap seconds)

  1. About daylight saving time documentation states the following:

Conversion operations between time zones (such as between UTC and local time, or between one time zone and another) take daylight saving time into account, but arithmetic and comparison operations do not.

That means that adding days (which is arithmetic operation) to DateTime instance, even if it has kind Local (so represents time in local timezone) does not take DST into account. That makes performing any arithmetic operations on datetimes with kind Local a really bad idea. If you need to do that with date times - first convert it to UTC (that has no notion of DST), perform operation then convert back to local (conversion as stated above does take DST into account).

You can also look at source code to see that datetime value is stored as a number internally (number of ticks) and adding days just adds fixed value to that number. Calculating hour\minute\second use that value and perform fixed operations (just a division) to obtain target value. None of those operations account for anything like leap seconds, time zones or anything else. So the answer to your question is yes.

like image 180
Evk Avatar answered Oct 12 '22 23:10

Evk