【发布时间】:2019-01-11 15:03:58
【问题描述】:
我正在寻找一个函数来获取 2 个日期(入院和出院)和一个财政年度,并返回这些日期之间每个月的天数。
财政年度为 4 月 1 日 -> 3 月 31 日
我目前有一个解决方案(如下),它是 SPSS 和 Python 的混乱,最终它需要重新实现到 SPSS 但作为一个更整洁的 Python 函数,不幸的是这意味着它只能使用标准库(而不是 Pandas )。
例如
+-----------------+------+------+--+--- --+-----+---+-----+------+-----+---+---+----- +-----+-----+------+ |入学 |放电 |风云 | |四月 |五月 |君 |七月 |八月 |九月 |十月 |十一月 |十二月 |一月 |二月 |三月 | +-----------------+------+------+--+--- --+-----+---+-----+------+-----+---+---+----- +-----+-----+------+ | 2017 年 1 月 1 日 | 2017 年 1 月 5 日 | 1617 | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | 0 | 0 | | 2017 年 1 月 1 日 | 2017 年 6 月 5 日 | 1617 | | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 31 | 28 | 31 | | 2017 年 1 月 1 日 | 2017 年 6 月 5 日 | 1718 | | 30 | 31 | 4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | 2017 年 1 月 1 日 | 2019 年 1 月 1 日 | 1718 | | 30 | 31 | 30 | 31 | 31 | 30 | 31 | 30 | 31 | 31 | 28 | 31 | +-----------------+------+------+--+--- --+-----+---+-----+------+-----+---+---+----- +-----+-----+------+相关 - How to calculate number of days between two given dates?
当前解决方案(SPSS 代码)
* 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.
【问题讨论】:
-
查看模块
datetime以获得正确的日期表示,并查看模块dateutil以将字符串可靠地解析为日期。 -
@Moohan 第三个参数的用途是什么,年份?开始日期和结束日期似乎已经包含了年份。
-
@JonahBishop 不是重复的。 OP 想要 每个月的天数。
-
如果给定的两个日期之间有两个 1 月,您想做什么?以 Jan: 62 或类似的结果结束?还是按年份分开?