I'm looking for a function to take 2 dates (admission and discharge) and a financial year and to return the number of days in each month between these too dates.
Financial year goes 1-April -> 31-March
I currently have a solution (below) which is a mess of SPSS and Python, ultimately it will need to be implemented back into SPSS but as a much tidyer Python function, unfortunately this means it can only use standard libraries (not Pandas).
e.g.
+-----------------+-----------------+------+--+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ | Admission | Discharge | FY | | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec | Jan | Feb | Mar | +-----------------+-----------------+------+--+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ | 01 January 2017 | 05 January 2017 | 1617 | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | 0 | 0 | | 01 January 2017 | 05 June 2017 | 1617 | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 31 | 28 | 31 | | 01 January 2017 | 05 June 2017 | 1718 | | 30 | 31 | 4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | 01 January 2017 | 01 January 2019 | 1718 | | 30 | 31 | 30 | 31 | 31 | 30 | 31 | 30 | 31 | 31 | 28 | 31 | +-----------------+-----------------+------+--+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
Related - How to calculate number of days between two given dates?
Current solution (SPSS code)
* Count the beddays.
* Similar method to that used in Care homes.
* 1) Declare an SPSS macro which will set the beddays for each month.
* 2) Use python to run the macro with the correct parameters.
* This means that different month lengths and leap years are handled correctly.
Define !BedDaysPerMonth (Month = !Tokens(1)
/MonthNum = !Tokens(1)
/DaysInMonth = !Tokens(1)
/Year = !Tokens(1))
* Store the start and end date of the given month.
Compute #StartOfMonth = Date.DMY(1, !MonthNum, !Year).
Compute #EndOfMonth = Date.DMY(!DaysInMonth, !MonthNum, !Year).
* Create the names of the variables e.g. April_beddays and April_cost.
!Let !BedDays = !Concat(!Month, "_beddays").
* Create variables for the month.
Numeric !BedDays (F2.0).
* Go through all possibilities to decide how many days to be allocated.
Do if keydate1_dateformat LE #StartOfMonth.
Do if keydate2_dateformat GE #EndOfMonth.
Compute !BedDays = !DaysInMonth.
Else.
Compute !BedDays = DateDiff(keydate2_dateformat, #StartOfMonth, "days").
End If.
Else if keydate1_dateformat LE #EndOfMonth.
Do if keydate2_dateformat GT #EndOfMonth.
Compute !BedDays = DateDiff(#EndOfMonth, keydate1_dateformat, "days") + 1.
Else.
Compute !BedDays = DateDiff(keydate2_dateformat, keydate1_dateformat, "days").
End If.
Else.
Compute !BedDays = 0.
End If.
* Months after the discharge date will end up with negatives.
If !BedDays < 0 !BedDays = 0.
!EndDefine.
* This python program will call the macro for each month with the right variables.
* They will also be in FY order.
Begin Program.
from calendar import month_name, monthrange
from datetime import date
import spss
#Set the financial year, this line reads the first variable ('year')
fin_year = int((int(spss.Cursor().fetchone()[0]) // 100) + 2000)
#This line generates a 'dictionary' which will hold all the info we need for each month
#month_name is a list of all the month names and just needs the number of the month
#(m < 4) + 2015 - This will set the year to be 2015 for April onwards and 2016 other wise
#monthrange takes a year and a month number and returns 2 numbers, the first and last day of the month, we only need the second.
months = {m: [month_name[m], (m < 4) + fin_year, monthrange((m < 4) + fin_year, m)[1]] for m in range(1,13)}
print(months) #Print to the output window so you can see how it works
#This will make the output look a bit nicer
print("\n\n***This is the syntax that will be run:***")
#This loops over the months above but first sorts them by year, meaning they are in correct FY order
for month in sorted(months.items(), key=lambda x: x[1][1]):
syntax = "!BedDaysPerMonth Month = " + month[1][0][:3]
syntax += " MonthNum = " + str(month[0])
syntax += " DaysInMonth = " + str(month[1][2])
syntax += " Year = " + str(month[1][1]) + "."
print(syntax)
spss.Submit(syntax)
End Program.