Forehead slapper on DateTime.AddDays()

I should have read the documentation for DateTime.AddDays() a little more carefully. This one caused a minor bug for me this week:

DateTime dt = DateTime.Now;
dt.AddDays(1);

What's in dt after the call to AddDays()? Well I assumed it would be this time tomorrow. However, from the .NET documentation for AddDays() I finally noticed: "This method does not change the value of this DateTime. Instead, a new DateTime is returned whose value is the result of this operation." Doh!

I should have written

DateTime dt = DateTime.Now;
dt = dt.AddDays(1);

That's what I get for not reading the docs, and instead assuming from the function's name that I know what it does (one of the downsides of Intellisense is it almost makes finding functions too easy). Although I'm not sure what would I have called the function AddDays() so its behavior would be more clear. Maybe something like: DateTime.ReturnNewDateTimeWithThisNumberOfDaysAddedToIt()...nah maybe not.

 

11 Comments

  • I have been bitten by this bug before as well. When I was first learning .Net I did that kind of thing with strings as well. Doh!!

  • DateTime dt = DateTime.Now.AddDays(1);



    I know current programming politeness asks you to use two lines, but I can't help sticking to my old C programming days... ;-)

  • I would agree with Edgar, but it seems actually too clever for the optimizer and it generates worse code ...

    The problem is , that the shorted method seems to be too clever for the CLR



    If you use the longer method, the optimizer generates it correctly into this



    [mscorlib]System.DateTime LongDate() cil managed

    {

    // Code size 25 (0x19)

    .maxstack 2

    .locals init (valuetype [mscorlib]System.DateTime V_0) <-- Notice just 1 instance of DateTime

    IL_0000: call valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now()

    IL_0005: stloc.0

    IL_0006: ldloca.s V_0

    IL_0008: ldc.r8 1.

    IL_0011: call instance valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::AddDays(float64)

    IL_0016: stloc.0

    IL_0017: ldloc.0

    IL_0018: ret

    } // end of method Class1::LongDate





    The shorter C# method creates two instances of DateTime !



    [mscorlib]System.DateTime ShortDate() cil managed

    {

    // Code size 25 (0x19)

    .maxstack 2

    .locals init (valuetype [mscorlib]System.DateTime V_0, valuetype [mscorlib]System.DateTime V_1)

    IL_0000: call valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now()

    IL_0005: stloc.1

    IL_0006: ldloca.s V_1

    IL_0008: ldc.r8 1.

    IL_0011: call instance valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::AddDays(float64)

    IL_0016: stloc.0

    IL_0017: ldloc.0

    IL_0018: ret

    } // end of method Class1::ShortDate

  • I'm still learning .NET, and I was trying to do a for loop to loop through a few dates. In my incremental I was doing i.AddDays(1) and for the life of me I couldn't figure out why it wouldn't increment until I came across this post. Thanks for putting it out there!

    for (DateTime i = startdate; i <= enddate; i=i.AddDays(1))
    {

    }

  • I was slapping myself on the forehead trying to figure the exact same bug out. Thank you for posting!

  • hallelujah, hallelujah!! thanks for posting : )

  • thank you very much

  • Gracias por el comentario, acabo de resolver mi problema

  • Thanks Loren. It's amazing that a blog post can still be valuable almost 5 years later.

    Mitch

  • I should email my friend about this.

  • и всё эе: благодарю... а82ч

Comments have been disabled for this content.