65.9K
CodeProject 正在变化。 阅读更多。
Home

月份中的星期几计算

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.89/5 (5投票s)

2007年12月26日

CPOL

3分钟阅读

viewsIcon

30476

downloadIcon

296

计算去年同一个月的星期几

引言

问题:我需要计算一年前同一月份的同一工作日的日期。

我最近遇到了一个我从未见过的日期计算场景。我进行了典型的网络搜索,但没有找到类似的内容,所以我开始思考并着手解决这个问题。 我为一家酒店管理公司工作。我们正在开发一个入住率报告系统。需求是计算酒店在“本月的工作日”去年的表现。例如:如果今天是 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 应用程序,用于测试日期。 我希望这能帮助到其他人。

© . All rights reserved.