Help with Dates

I’m doing something wrong. I need to get the month and year of last six months from the current date. I tried:

Dim dt As New Date

For i as Integer = 1 to 6
… Get the dt.month and dt.year and do some processing
dt.month = dt.month - 1
Next

Today is 12/31. This doesn’t work because there is no November 31, so instead I get December 1 instead of November. I also need this to decrement the year when appropriate as well - January 1, 2020 results in Dec 2019 when subtracting one month.

I am overlooking something simple here…

If you only need the month and the year and not the day , especially if you would then be taking dt.month and dt.year as Integers and working with them instead of using a Date (or DateTime) in your code, you’re going to be much better off doing this yourself than trying to use a delta on a Date. Something like this, perhaps:

Function PrevMonth(curMonth As Integer, curYear As Integer) As Pair
  curMonth = curMonth - 1
  If curMonth = 0 Then
    curMonth = 12
    curYear = curYear - 1
  End If
  Return New Pair(curMonth, curYear)
End Function

(Disclaimer: written in forum editor; not tested)

Of course, some sanity checks on curMonth and curYear would also be appropriate.

Alternatively to the Pair I used, you could pass the arguments ByRef and modify the variables directly.

dt.month = dt.month - 1

you must be doing some else… because this subtracts a MONTH, not 30 or 31 days

when I run this

Dim dt As New date
For i As Integer=1 To 6
  debug dt.ShortDate
  dt.month=dt.month-1
Next i
break

I get this
12/31/19
11/30/19
10/30/19
9/30/19
8/30/19
7/30/19

My Opinon… let DATE do the work, no need for a band-aid type function…

Dave, totally agree with you that one shouldn’t reinvent the wheel. I didn’t do due diligence to verify that Date wasn’t doing the right thing before replying.

and DATE is doing the right thing :slight_smile: something the OP did altered what he thought was happening as I showed above

[quote=469727:@Dave S] dt.month = dt.month - 1
you must be doing some else… because this subtracts a MONTH, not 30 or 31 days

when I run this

Dim dt As New date
For i As Integer=1 To 6
  debug dt.ShortDate
  dt.month=dt.month-1
Next i
break

I get this
12/31/19
11/30/19
10/30/19
9/30/19
8/30/19
7/30/19[/quote]

Dave, I agree and that is what I was expecting. However, this might be a bug (?)

Drop this in the action of a button:

[code]Sub Action() Handles Action
Dim dt1 As New Date
Dim dt2 As New Date

dt2.month = dt2.month - 1

MsgBox dt1.ShortDate + " " + dt2.Shortdate
End Sub
[/code]

I get “12/31/2019 12/1/2019” which was unexpected.

What do you get?

FYI i am on windows.

so its a WINDOWS problem as I am on macOS

what version of Xojo and what version of Windows

I am on Windows 10 / Xojo 2019r1.1

But this begs the question, what is subtracting the month really doing under the hood? does this really deal with leap year and shorter months? What happens on your system if you go back 12 months - What day in each month does it generate?

Well on macOS it would do what you expect…
Yes it handles leap year, yes it handles adding or subtracting any number of days or months … however if you do both… .do the months first.

but it seems the WIndows implementation is bonked to say the least

I think how you need to handle it will depend on what your definition of subtracting a month is. X number of days? X number of weeks? As you’ve seen, just decrementing the month in a date won’t necessarily give you a valid (or expected) date.

But it has to do something else besides just subtract 1 from the month as 2/31/2019 is not a valid date and according to the docs would throw an UnsupportedFormatException. How does it arrive at a specific day in the new date when subtracting a month? What is a “month”?

I agree and after thinking about it Ed’s solution is where I am headed.

And as an aside which may be useful, to get the last day of a month, set your date to the first day of the following month and subtract a day:

dim d as new date d.day = 1 d.Month = 7 d.year = 2019 d.day = d.day -1

only in Windows… in macOS it DOES exactly what is expected.
A month is “a month”, it is not a set number of days (as it can vary from 28 to 31)… it is most definitey NOT a number “weeks” as that would be dependent on when the month started or ended.

The correct “answer” is

y=dt.year
m=dt.month
d=dt.day
m=m-1
if m<0 then
m=12
y=y-1
end if
while d>days in month(m) then d=d-1

THAT is pseduo code for what SHOULD happen “under the hood”

[quote=469739:@Scott Griffitts]And as an aside which may be useful, to get the last day of a month, set your date to the first day of the following month and subtract a day:

dim d as new date d.day = 1 d.Month = 7 d.year = 2019 d.day = d.day -1[/quote]

That’s a good workaround for this, thanks.