我正在寻找一种最聪明的算法,用于确定特定系列中给定日历月内每两周发生一次的事件的数量。
即。鉴于该系列节目是“2010年10月7日每周二的第二个星期四”,“事件”正在下降(2010年10月7日,10月21日,11月4日,11月18日,12月2日,12月16日,12月30日......)
所以我所追求的是一个功能
function(seriesDefinition, month) -> integer
where:
- seriesDefinition is some date that is a valid date in the series,
- month indicates a month and a year
这样就可以准确地确定:numberFortnightlyEventsInSeriesThatFallInCalendarMonth
示例:
NumberFortnightlyEventsInMonth('2010年10月7日,'2010年10月') - > 2
NumberFortnightlyEventsInMonth('2010年10月7日,'Nov2010') - > 2
NumberFortnightlyEventsInMonth('2010年10月7日,'2010年12月') - > 3
请注意,10月有2个事件,11月有2个事件,但12月有3个事件。
Psuedocode首选。
我不想依赖查找表或Web服务调用或除潜在通用库之外的任何其他外部资源。例如,我认为我们可以放心地假设大多数编程语言都有一些可用的日期操作函数。
答案 0 :(得分:0)
处理日期时没有“聪明”的算法,只有繁琐的算法。也就是说,你必须具体列出每个月的天数,处理闰年(每四年一次,除了每100年除外,每400年除外)等。
答案 1 :(得分:0)
嗯,对于您所说的算法,通常的解决方案是从某个固定日期开始计算日期数。 (天数加上上个月的累计天数加上年数* 365减去(年数/ 4)加上(年数/ 100)减去(年数/ 400))
有了这个,你可以轻松实现你需要的东西。你需要计算一周中的哪一天是1月1日。那么你可以很容易地看到从那天到2010年10月1日和2010年12月1日的“每隔一个星期四”的数量。他们的差异是你正在寻找的价值
答案 2 :(得分:0)
我的解决方案......
Public Function NumberFortnightlyEventsInMonth(seriesDefinition As Date, month As String) As Integer
Dim monthBeginDate As Date
monthBeginDate = DateValue("1 " + month)
Dim lastDateOfMonth As Date
lastDateOfMonth = DateAdd("d", -1, DateAdd("m", 1, monthBeginDate))
' Step 1 - How many days between seriesDefinition and the 1st of [month]
Dim daysToMonthBegin As Integer
daysToMonthBegin = DateDiff("d", seriesDefinition, monthBeginDate)
' Step 2 - How many fortnights (14 days) fit into the number from Step 1? Round up to the nearest whole number.
Dim numberFortnightsToFirstOccurenceOfSeriesInMonth As Integer
numberFortnightsToFirstOccurenceOfSeriesInMonth = (daysToMonthBegin \ 14) + IIf(daysToMonthBegin Mod 14 > 0, 1, 0)
' Step 3 - The date of the first date of this series inside that month is seriesDefinition + the number of fortnights from Step 2
Dim firstDateOfSeriesInMonth As Date
firstDateOfSeriesInMonth = DateAdd("d", (14 * numberFortnightsToFirstOccurenceOfSeriesInMonth), seriesDefinition)
' Step 4 - How many fortnights fit between the date from Step 3 and the last date of the [month]?
NumberFortnightlyEventsInMonth = 1 + (DateDiff("d", firstDateOfSeriesInMonth, lastDateOfMonth) \ 14)
End Function