Stata:两个日期之间的月数
Stata: Number of Months between Two Dates
我想创建一个变量,它给出我的数据集中两个每日日期变量(end_date 和 start_date)之间的月数。如果它是该月的第一天,我想计算开始日期的月份,同样,如果它是该月的最后一天,我想计算结束日期的月份。
例如,假设 start_date 是 01feb2010,end_date 是 12jun2010。我想计算二月以及二月和六月之间的月份,但不计算六月。所以,总共4个月。
这是一个非常粗略的解决方案:
gen diff_days = end_date - start_date
gen diff_months = floor(diff_days/30.437)
list
+---------------------------------------------+
| start_d~e end_date diff_d~s diff_m~s |
|---------------------------------------------|
1. | 01feb2010 12jun2010 131 4 |
2. | 01feb2010 01feb2011 365 12 |
3. | 01feb2010 27jun2010 146 4 |
+---------------------------------------------+
可能有更好的方法来做到这一点。请注意,平均日历月长度为 30.437 天。
扩展@Cybernike 的有用答案:
您似乎想要一个开始日期和另一个结束日期之间的完整月数。将每天的日期推过mofd()
得到差值是一个答案的基础,除了一般情况下我们需要加1,除非结束日期是它所在月份的最后一天,否则还要减1。
跟着我重复:当月的最后一天是下个月的第一天的前一天。下个月的第一天很容易找到,然后您需要做的就是减去 1 以获得当月最后一天的每日日期。无需检查不同的月份长度,31、30、29 或 28 天。有一篇关于这个主题的论文。参见 here。
clear
input float(start end)
18294 18425
18294 18659
18294 18440
18294 18474
18295 18474
end
gen end2 = dofm(mofd(end) + 1) - 1
gen start2 = dofm(mofd(start))
format %td start* end*
gen wanted1 = mofd(end) - mofd(start) + 1 - (end2 != end)
gen wanted2 = mofd(end) - mofd(start) + 1 - (start2 != start) - (end2 != end)
list
+-------------------------------------------------------------------+
| start end end2 start2 wanted1 wanted2 |
|-------------------------------------------------------------------|
1. | 01feb2010 12jun2010 30jun2010 01feb2010 4 4 |
2. | 01feb2010 01feb2011 28feb2011 01feb2010 12 12 |
3. | 01feb2010 27jun2010 30jun2010 01feb2010 4 4 |
4. | 01feb2010 31jul2010 31jul2010 01feb2010 6 6 |
5. | 02feb2010 31jul2010 31jul2010 01feb2010 6 5 |
+-------------------------------------------------------------------+
但是,你的问题有歧义。开始日期可以不是一个月的第一天吗?如果是这样,那么您是否也需要检查该条件?请参阅 wanted2
以获得更严格的解决方案。
我想创建一个变量,它给出我的数据集中两个每日日期变量(end_date 和 start_date)之间的月数。如果它是该月的第一天,我想计算开始日期的月份,同样,如果它是该月的最后一天,我想计算结束日期的月份。
例如,假设 start_date 是 01feb2010,end_date 是 12jun2010。我想计算二月以及二月和六月之间的月份,但不计算六月。所以,总共4个月。
这是一个非常粗略的解决方案:
gen diff_days = end_date - start_date
gen diff_months = floor(diff_days/30.437)
list
+---------------------------------------------+
| start_d~e end_date diff_d~s diff_m~s |
|---------------------------------------------|
1. | 01feb2010 12jun2010 131 4 |
2. | 01feb2010 01feb2011 365 12 |
3. | 01feb2010 27jun2010 146 4 |
+---------------------------------------------+
可能有更好的方法来做到这一点。请注意,平均日历月长度为 30.437 天。
扩展@Cybernike 的有用答案:
您似乎想要一个开始日期和另一个结束日期之间的完整月数。将每天的日期推过mofd()
得到差值是一个答案的基础,除了一般情况下我们需要加1,除非结束日期是它所在月份的最后一天,否则还要减1。
跟着我重复:当月的最后一天是下个月的第一天的前一天。下个月的第一天很容易找到,然后您需要做的就是减去 1 以获得当月最后一天的每日日期。无需检查不同的月份长度,31、30、29 或 28 天。有一篇关于这个主题的论文。参见 here。
clear
input float(start end)
18294 18425
18294 18659
18294 18440
18294 18474
18295 18474
end
gen end2 = dofm(mofd(end) + 1) - 1
gen start2 = dofm(mofd(start))
format %td start* end*
gen wanted1 = mofd(end) - mofd(start) + 1 - (end2 != end)
gen wanted2 = mofd(end) - mofd(start) + 1 - (start2 != start) - (end2 != end)
list
+-------------------------------------------------------------------+
| start end end2 start2 wanted1 wanted2 |
|-------------------------------------------------------------------|
1. | 01feb2010 12jun2010 30jun2010 01feb2010 4 4 |
2. | 01feb2010 01feb2011 28feb2011 01feb2010 12 12 |
3. | 01feb2010 27jun2010 30jun2010 01feb2010 4 4 |
4. | 01feb2010 31jul2010 31jul2010 01feb2010 6 6 |
5. | 02feb2010 31jul2010 31jul2010 01feb2010 6 5 |
+-------------------------------------------------------------------+
但是,你的问题有歧义。开始日期可以不是一个月的第一天吗?如果是这样,那么您是否也需要检查该条件?请参阅 wanted2
以获得更严格的解决方案。