Manipulating date class in multiple steps gives incorrect result

In this conversation I was looking at getting the last day of the following month specifically 28th February 2013, but with a generic function that would work on any month in any year. The code I thought was quite simple.

[code] Dim d As New Date
d.day = 31
d.Month = 1
d.year = 2013

d.day = d.day + 40
d.day = 1
d.day = d.day - 1
MsgBox d.ShortDate
[/code]

Stepping through the code d.day = d.day + 40 gives me 12th March, d.day = 1 gives me 1st March, d.day = d.day - 1 gives me 28th Feb. However when I ran the app I got 31st December 2012.

What is strange is that if I inspect the date properties during debug I get the right answer.

<https://xojo.com/issue/27974>

The date’s properties “roll over” or autocorrect when you access them. You haven’t done that, so

[code]Dim d As New Date
d.day = 31
d.Month = 1
d.year = 2013

d.day = d.day + 40 // Month is 1, Day is 71
d.day = 1 // Month is 1, Day is 1
d.day = d.day - 1 // Month is 1, Day is 0
MsgBox d.ShortDate // Only now do Month and Year get updated.[/code]

But if you access the date, it will update:

[code]Dim d As New Date
d.day = 31
d.Month = 1
d.year = 2013

d.day = d.day + 40
dim n as integer = d.day // Month is now 3, Day is 12
d.day = 1
d.day = d.day - 1
MsgBox d.ShortDate[/code]

Do yourself a favor and always set the bigger values first:

Year
Month
Day
Hour
Minute
Second

You’ll have a much better experience with dates this way.

Also, the Date class has some constructors that take parameters for setting up dates.

http://documentation.xojo.com/index.php/Date

Back in 2006/2007 or so, the month would update immediately on setting the day. That was deemed a bug because it produced unpredictable results, especially at the end of each month. The current behavior is much better, although you have to be careful about not stepping through date manipulation code in the debugger, because the debugger accesses the date’s values and will cause them to adjust prematurely.

Thanks for your explanation Tim. The LR really should have something about this.

You can use

[code] Dim d As New Date
d.day = 31
d.Month = 1
d.year = 2013

d.day = 1 ’ First day of current month
d.month = d.month + 2 ’ First day of two months forward
d.day = d.day - 1 ’ last day of next month

[/code]

Yes I understand this is the best way, I was just confused on the debug/inspect model.