我将在这里投入我的两美分,第三个选项是根据找到每天的第一天得到它,然后添加 7 的倍数以获得最终结果。
功能
CREATE FUNCTION `ISNTHDAYINMONTH`(checkDate DATE, weekNumber INTEGER, dayOfWeek INTEGER, monthOfYear INTEGER) RETURNS INTEGER
NO SQL
DETERMINISTIC
BEGIN
DECLARE firstOfMonth DATE;
SET firstOfMonth = DATE_SUB(checkDate, INTERVAL DAYOFMONTH(checkDate) - 1 DAY); #Find the first day of the current month
IF DAYOFWEEK(checkDate) = dayOfWeek AND MONTH(checkDate) = monthOfYear #Make sure at least this matches
AND DAYOFMONTH(checkDate) = ((1 + (7 + dayOfWeek - DAYOFWEEK(firstOfMonth)) % 7) + 7 * (weekNumber - 1)) THEN #When the date matches the nth dayOfWeek day of the month
RETURN 1;
ELSE
RETURN 0; #Nope
END IF;
END
利用
SELECT ISNTHDAYINMONTH(datecol, weekNumber, dayOfWeek, monthOfYear);
其中 weekNumber 是 1 到 5,dayOfWeek 是 1 到 7(1 = 太阳),monthOfYear 是 1 到 12。
例子
要检查 datecol 是否是 4 月的第二个星期二:
SELECT ISNTHDAYINMONTH(datecol, 2, 3, 4);
计算
让我们分解一下。此行获取传入日期的月份的第一天。
SET firstOfMonth = DATE_SUB(checkDate, INTERVAL DAYOFMONTH(checkDate) - 1 DAY); #Find the first day of the current month
此检查确保日期具有正确的星期几和正确的月份(以防用户输入的日期甚至不是星期几)。
DAYOFWEEK(checkDate) = dayOfWeek AND MONTH(checkDate) = monthOfYear
现在是大的:
DAYOFMONTH(checkDate) = ((1 + (7 + dayOfWeek - DAYOFWEEK(firstOfMonth)) % 7) + 7 * (weekNumber - 1))
为了得到我们需要添加到 1 以获取日期的数量,我们计算我们正在查看的 dayOfWeek,减去该月的第一天所在的星期几,以获得偏移量 mod 7 ((dayOfWeek - DayOfWeek (第一)) % 7)。
请注意,由于本月的第一天可能会在我们正在查看的前一天或当天降落,因此我们添加了额外的 7,然后再增加 7。这是必需的,因为 MySQL 的 Mod 函数不能正确计算 mod。即 -1 % 7 应该是 6,但 MySQL 返回 -1。添加 7 并取模可确保结果始终正确。
总结一下:
NumberToAddToOneToGetDateOfFirstWeekDay = (7 + DayOfWeek - DayOfWeek(firstDayOfMonth)) %
然后我们添加一个以及需要多少个 7 才能到达正确的一周。