月份中的星期几计算
计算去年同一个月的星期几
引言
问题:我需要计算一年前同一月份的同一工作日的日期。
我最近遇到了一个我从未见过的日期计算场景。我进行了典型的网络搜索,但没有找到类似的内容,所以我开始思考并着手解决这个问题。 我为一家酒店管理公司工作。我们正在开发一个入住率报告系统。需求是计算酒店在“本月的工作日”去年的表现。例如:如果今天是 1 月的第三个星期日,那么酒店去年 1 月的第三个星期日表现如何? 事实证明,这是一项比我所想的更具挑战性的任务。
我可以循环遍历每个月,但我有几个月需要生成,所以这似乎不是一个好主意。
我也考虑过根据一年中的周数进行计算。但是月份中的周数差异让我很头疼。
我意识到我有一些固定的信息,并且可能可以快速计算日期,从而避免每次屏幕刷新时循环 1-31 x 365 次。
使用代码
我们知道的固定信息是
- 输入的月份
- 输入的年份
- 目标月份
- 目标年份
- 输入月份的天数
- 目标月份的天数
- 一周有 7 天。
计算仅输出目标月份的 1 到 31 之间的数字作为日期。由于并非所有月份都从星期日开始,并且每年看起来都不同,因此我计算了每个月的“偏移量”。这是使用 DayOfWeek 函数计算的,用于每个月的第一天。
首先,我用已知信息加载了一些变量。
iInMonth = dInDate.Month
iInYear = dInDate.Year
iInWeekDay = dInDate.DayOfWeek
dInWeek = Math.Ceiling((dInDate.Day + iInOffset) / 7) '*** CALCULATE THE WEEK OF THE MONTH ****
iInOffset = New Date(iInYear, iInMonth, 1).DayOfWeek
iOutOffset = New Date(iInYear - 1, iInMonth, 1).DayOfWeek
然后我可以使用以下公式计算出潜在的 目标日期。
X = ((传入的周数 * 一周 7 天) - (6 - 传入的星期几) ) - 输出偏移量
分解一下
(传入的周数 x 一周 7 天) 将给我目标周的星期六
(6 - 传入的星期几) 将从星期六中减去以给我正确的星期几
减去输出月份的偏移量将调整月份之间的差异
因此,获得正确工作日的计算是
'*********************************
'*** CALCULATE THE TARGET DATE ***
'*********************************
dDayCalc = ((dInWeek * 7) - (6 - iInWeekDay)) - iOutOffset
这几乎可以工作,但我发现了一些需要考虑的场景。
第一点 - 计算可能会返回超出我们 1-31 计算范围的非日期。 月初的部分周有时会将我的计算推回到上一个月。 也称为计算为负数的日期。 例如,如果本月的第一周没有星期五,而是从星期六开始,它将返回一个负数。
第二点 - 闰年可以改变一个月中有多少周。 这会导致问题,尤其是在 2008 年 2 月(5 周)和 2009 年 2 月(4 周)。
第三点 - 计算的日期可能已经超过了月底。 闰年是另一个例子。
'*************************
'**** ANOMALY CATCHES ****
'*************************
If dDayCalc <= 0 Then
'*** CALCULATION RETURNS NON DATE
dDayCalc += 7
ElseIf (Date.DaysInMonth(dInDate.Year - 1, dInDate.Month) / 7) > (Date.DaysInMonth(dInDate.Year, dInDate.Month) / 7) _
And iInWeekDay < iOutOffset Then
'*** IF THERE ARE MORE WEEKS IN THE OUTMONTH THAN THE
'*** IN MONTH WE NEED TO ADD 1 WEEK.
'*** THIS OCCURS AS A RESULT OF LEAP YEAR FOR EXAMPLE FEB 2009 - FEB 2008
dDayCalc += 7
ElseIf dDayCalc > Date.DaysInMonth(dInDate.Year - 1, dInDate.Month) Then
'*** CALCULATION RETURNS DATE MORE THAN IN MONTH
Return Nothing
End If
结论
事实证明,这是一项相当容易的任务,但只需要一些思考。 我相信还有很多其他方法可以完成这项任务,但此时这对我来说似乎有意义。 包含的项目文件是一个快速而肮脏的 VB.NET Windows 应用程序,用于测试日期。 我希望这能帮助到其他人。