A challenge: adding months to a date?

David Bovill david at openpartnership.net
Sun May 13 11:19:14 EDT 2007


I thought this was easy! Well I discovered a bug in some old code and now I
am pulling my hair out trying to fix / code this... an interesting puzzle
for those of you so inclined on a Sunday :)

The Task
The function needs to add a variable number of months to a given date:

function date_AddMonth monthNum, startDate
    ....
end date_AddMonth

Seems easy no?

Use Case
I have some bank statements with statement numbers issued each calendar
month. First statement is numbered 01 and is for October 2002. I want to
work out what the month and year is for the nth statement.

First Try

function date_AddMonth monthNum, startDate
    convert startDate to dateItems
    put startDate into someDate

    put item 2 of someDate into oMonthNum
    put oMonthNum + monthNum into overMonthNum

    put overMonthNum into item 2 of someDate
    convert someDate to dateItems

    return someDate
end date_AddMonth

I thought this worked fine, but if the startdate is lets say January 31 -
well adding a month basically goes to Feb 31st which converts to March... so
you need to do something else.... but what??? Been trying a few hours now
and things have got complicated involving for a start working out leap
years!

Unit Test
Well if anyone can figure this out - here is the test to pass:

on mouseUp
    -- put "Friday, January 31, 2002" into abbeyStartDate
    put "2002,1,31,1,0,0,5" into abbeyStartDate
    put 1 into lastMonth
    repeat with statementNumber = 1 to 100
        put item 2 of date_AddMonth(statementNumber, abbeyStartDate) into
someMonth
        put someMonth
        if statementNumber mod 12 is not (someMonth - 1) then
        put merge("Failed adding [[statementNumber]] to [[abbeyStartDate]].
Resulted in [[someMonth]]")
            answer "Failed!"
            exit to top
        end if
    end repeat
    answer "Success!!"
end mouseUp

I cant figure it out???

More Problems
Sometimes when you dig things just get more complex. While debugging i am
finding that sometime adding numbers to the 2nd item of the dateitems and
then reconverting to dateitems works fine, and then mysteriously at others
it does not... seemingly getting confused by having the wrong daynum in item
7... still not figured what is going on...

Stuff that may help?
Here is a function you may need (well thats the direction I am trying):

function date_MaxDaysInMonth someDate
    /*
    Base on the rhyme:
    30 dyays has September, April, June and Novemeber
    All the rest have 31
    Except Februaruy
    Which has 28 and 29 on a leap year
    */

    convert someDate to dateItems
    put item 2 of someDate into monthNum

    return date_MaxDaysInMonthNum(monthNum)
end date_MaxDaysInMonth

function date_MaxDaysInMonthNum monthNum
    /*
    Base on the rhyme:
    30 days has September, April, June and Novemeber
    All the rest have 31
    Except Februaruy
    Which has 28 and 29 on a leap year
    */

    put 30 into item 9 of maxDaylist
    put 30 into item 4 of maxDaylist
    put 30 into item 6 of maxDaylist
    put 30 into item 11 of maxDaylist

    put 31 into item 1 of maxDaylist
    put 31 into item 3 of maxDaylist
    put 31 into item 5 of maxDaylist
    put 31 into item 7 of maxDaylist
    put 31 into item 8 of maxDaylist
    put 31 into item 10 of maxDaylist
    put 31 into item 12 of maxDaylist

    if date_IsLeapYear(someDate) then
        put 29 into item 2 of maxDaylist
    else
        put 28 into item 2 of maxDaylist
    end if

    return item monthNum of maxDaylist
end date_MaxDaysInMonthNum

function date_IsLeapYear someDate
    convert someDate to dateitems
    put 2 into item 2 of someDate
    put 29 into item 3 of someDate
    convert someDate to dateitems
    return item 2 of someDate = 2
end date_IsLeapYear

- but maybe someone already has a simple function that passes this test?



More information about the use-livecode mailing list