首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Server日期逻辑-查找下一个提醒日期

Server日期逻辑-查找下一个提醒日期
EN

Stack Overflow用户
提问于 2011-06-22 19:41:12
回答 2查看 1.7K关注 0票数 1

给定以下数据库表:

代码语言:javascript
复制
StartDate DATETIME  -- day that the reminder period starts
LastReminderDate DATETIME -- the last time the reminder triggered
DayOfMonth INT -- the day of the month to remind the user
Interval INT   -- how often in months to remind the user

如何根据这些值计算下一个提醒日期?例如:

代码语言:javascript
复制
StartDate = '6/1/2011'
LastReminderDate = '6/5/2011'
DayOfMonth = 5 -- remind on the 5th of the month
Interval = 2 -- remind every other month

对于这个特别的例子,下一个提醒日期应该是2011年5月8日,因为它每两个月提醒一次。我将如何编写一个函数来解决这个问题?

如果LastReminderDate为NULL,则LastReminderDate应等于StartDate

更新:

代码语言:javascript
复制
StartDate = '6/1/2011'
LastReminderDate = NULL
DayOfMonth = 5
Interval = 2

在这种情况下,没有最后的提醒日期。第一次发出提醒将是2011年5月6日。在这种情况下,下面的解决方案似乎返回了8/5。

以下是一些具体的规则:

  • ,无论DayOfMonth是什么,提醒都应该发生。如果DayOfMonth在给定的月份是非法的,那么它应该是那个月的最后一天。对于example....if DayOfMonth是31岁,下一个提醒日期是6月31日,然后应该是6月30日。下一个提醒日期
  • 应该总是以最后提醒日期加上间隔时间为基础。如果“最后一次提醒”日期与月份的日期不匹配,则可能会超过间隔时间。对于example...if,最后一次提醒为6/1/2011,间隔为2个月,但提醒为该月份的20次,则下一次提醒为8/20/2011。如果没有最后提醒日期,则使用
  • ,然后使用开始日期而不是最后一次提醒date...but --这将使用未来最早的日期。如果开始日期是2011年6月1日,月的日期是5,那么这将是7/5/2011,因为今天是6/22/2011。如果月日是25,那么2011年6月25日是
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-06-22 19:50:05

代码语言:javascript
复制
DECLARE
@StartDate AS datetime,  -- day that the reminder period starts
@LastReminderDate AS datetime, -- the last time the reminder triggered
@DayOfMonth AS integer, -- the day of the month to remind the user
@Interval AS integer   -- how often in months to remind the user

SET @StartDate = '6/1/2011'
SET @LastReminderDate = '6/5/2011'
SET @DayOfMonth = 5 -- remind on the 5th of the month
SET @Interval = 2 -- remind every other month

SELECT
CASE
   WHEN @LastReminderDate IS NULL
   THEN
     CASE WHEN Day(@StartDate) <= @DayOfMonth
       THEN DateAdd( month, ((Year( @StartDate ) - 1900) * 12) + Month( @StartDate ) - 1, @DayOfMonth - 1 )
       ELSE DateAdd( month, ((Year( @StartDate ) - 1900) * 12) + Month( @StartDate ) - 0, @DayOfMonth - 1 )
     END
  ELSE DateAdd( month, @Interval, @LastReminderDate )
END

它的核心是最后四行,SELECT CASE ... END语句。我提供了一个完整的脚本,允许您插入不同的值,并查看SELECT CASE ... END如何处理这些测试值。

但是,要在您的表上使用这一点,只需使用最后四行(并从名称的前面删除@,以便它们与表的列名匹配)。

您也可以概括这一点,这样间隔就不必是几个月了。如果表中有IntervalType列,则可以将其作为第一个参数提供给DateAdd()。请参阅文档,但一些常见的间隔是daysmonthsyears等。

EDIT2:尊重DayOfMonth。

票数 2
EN

Stack Overflow用户

发布于 2011-06-22 19:58:19

由于您希望在没有StartDate的情况下使用LastReminderDate,那么您将希望对这一点逻辑使用合并:COALESCE(LastReminderDate, StartDate)

现在开始前一个月的最后一个月:DATEADD(DAY, -DAY(COALESCE(LastReminderDate, StartDate)), COALESCE(LastReminderDate, StartDate))

最后,将月份相加,然后到达我们需要的日期:

代码语言:javascript
复制
DATEADD(MONTH, Interval, DATEADD(DAY, -DAY(COALESCE(LastReminderDate, StartDate)) + DayOfMonth, COALESCE(LastReminderDate, StartDate)))

如果最后一次提醒的日期是在为提醒配置的"DayOfMonth“之后的一个月的某一天,这可能会持续不到两个月。您应该能够根据您的业务逻辑在这种情况下对其进行调整。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6445542

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档