SQL Server时间算法总结

本文提供了一系列SQL Server中日期和时间的计算方法,包括获取指定日期的前后一天、月初月末、季度初末等,并介绍了如何判断闰年和平年。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1: 

DECLARE

@Date

  DATETIME    2: 

SET

@Date

=GETDATE()    3: 

--前一天,给定日期的前一天    4: 

SELECT

DATEADD(DAY

,-1,@Date

) AS

'前一天'

    5: 

--后一天,给定日期的后一天  飞鸽传书  6: 

SELECT

DATEADD(DAY

,1,@Date

) AS

'后一天'

    7: 

GO

    8: 

    9: 

  10: 

--月初,计算给定日期所在月的第一天  11: 

--这个计算的技巧是先计算当前日期到“1900-01-01”的时间间隔数,然后把它加到“1900-01-01”上来获得特殊的日期,这个技巧可以用---来计算很多不同的日期。  12: 

DECLARE

@Date

  DATETIME  13: 

SET

@Date

=GETDATE()  14: 

SELECT

DATEADD(MONTH

,DATEDIFF(MONTH

,'1900-01-01'

,@Date

),'1900-01-01'

) AS

'所在月的第一天'

  15: 

--精简算法,根据SQL Server的时间表示方式可知,'1900-01-01'

可以用0代替  16: 

SELECT

DATEADD(MONTH

,DATEDIFF(MONTH

,0,@Date

),0) AS

'所在月的第一天'

  17: 

--上面两种算法精确到天 时分秒均为00:00:00.000  18: 

--下面算法课以保留时分秒 http://www.freeeim.com/  19: 

--思路:用给定日期减去月第一天与给定日期差的天数  20: 

SELECT

DATEADD(DAY

,1-DATEPART(DAY

,@Date

),@Date

)  21: 

GO

  22: 

  23: 

--月末,计算给定日期所在月的最后一天  24: 

DECLARE

@Date

  DATETIME  25: 

SET

@Date

=GETDATE()  26: 

--思路:当前月的下一月1号在减1天  27: 

SELECT

DATEADD(DAY

,-1,DATEADD(MONTH

,1+DATEDIFF(MONTH

,'1900-01-01'

,@Date

),'1900-01-01'

)) AS

'所在月的最一天'

  28: 

SELECT

DATEADD(MONTH

,1+DATEDIFF(MONTH

,'1900-01-01'

,@Date

),'1900-01-01'

)-1 AS

'所在月的最一天'

  29: 

--1900-01-01 用0代替  30: 

SELECT

DATEADD(DAY

,-1,DATEADD(MONTH

,1+DATEDIFF(MONTH

,0,@Date

),0)) AS

'所在月的最一天'

  31: 

SELECT

DATEADD(MONTH

,1+DATEDIFF(MONTH

,0,@Date

),0)-1 AS

'所在月的最一天'

  32: 

--思路:与月初计算思路相同  33: 

SELECT

DATEADD(MONTH

,DATEDIFF(MONTH

,'1989-12-31'

,@Date

),'1989-12-31'

) AS

'所在月的最一天'

  34: 

--精简算法,'1989-12-31'

用-1代替  35: 

SELECT

DATEADD(MONTH

,DATEDIFF(MONTH

,-1,@Date

),-1) AS

'所在月的最一天'

  36: 

--保留时分秒的算法  37: 

SELECT

DATEADD(DAY

,-1,DATEADD(MONTH

,1,DATEADD(DAY

,1-DATEPART(DAY

,@Date

),@Date

)))  38: 

GO

  39: 

  40: 

--其他月计算  41: 

  42: 

--计算给定日期所在月的上月第一天  43: 

DECLARE

@Date

  DATETIME  44: 

SET

@Date

=GETDATE()  45: 

--当前月第一天减去一个月  46: 

SELECT

DATEADD(MONTH

,-1,DATEADD(MONTH

,DATEDIFF(MONTH

,0,@Date

),0)) AS

'上月第一天'

  47: 

--简化  48: 

SELECT

DATEADD(MONTH

,DATEDIFF(MONTH

,0,@Date

)-1,0) AS

'上月第一天'

  49: 

--另一种当前月第一天算法  50: 

SELECT

DATEADD(MONTH

,-1,DATEADD(DAY

,1-DATEPART(DAY

,@Date

),@Date

)) '上月第一天'

  51: 

GO

  52: 

  53: 

--计算给定日期所在月的上月最后一天  54: 

DECLARE

@Date

  DATETIME  55: 

SET

@Date

=GETDATE()  56: 

--当前月第一天减去一天  57: 

SELECT

DATEADD(DAY

,-1,DATEADD(MONTH

,DATEDIFF(MONTH

,0,@Date

),0)) AS

'上月最后一天'

  58: 

--另一种当前月第一天算法  59: 

SELECT

DATEADD(DAY

,-1,DATEADD(DAY

,1-DATEPART(DAY

,@Date

),@Date

)) '上月最后一天'

  60: 

SELECT

DATEADD(DAY

,1-DATEPART(DAY

,@Date

),@Date

)-1 '上月最后一天'

  61: 

--另一种算法,不能用当前月的最后一天加一个月,因为当前月可能是30天。  62: 

--例如 SELECT

DATEADD(MONTH

,1,'2010-06-30'

) --结果是2010-07-30而不是2010-07-31,  63: 

--这也是月末算法采用下月第一天减1天计算的原因  64: 

--但是如果计算月是31天择无此问题  65: 

--例如 SELECT

DATEADD(MONTH

,1,'2010-05-31'

) --结果是2010-06-30  66: 

--因此下面算法是正确的,-1 表示'1899-12-31 00:00:00.000'

-- SELECT CONVERT(DATETIME,-1) 

  67: 

SELECT

DATEADD(MONTH

,DATEDIFF(MONTH

,-1,@Date

)-1,-1)  68: 

--另一种当前月算法  69: 

SELECT

DATEADD(DAY

,-1,DATEADD(DAY

,1-DATEPART(DAY

,@Date

),@Date

)) '上月最后一天'

  70: 

--简化  71: 

SELECT

DATEADD(DAY

,0-DATEPART(DAY

,@Date

),@Date

) '上月最后一天'

  72: 

GO

  73: 

  74: 

--计算给定日期所在月的下月第一天  75: 

DECLARE

@Date

  DATETIME  76: 

SET

@Date

=GETDATE()  77: 

--当前月第一天加一个月  78: 

SELECT

DATEADD(MONTH

,1,DATEADD(MONTH

,DATEDIFF(MONTH

,0,@Date

),0)) AS

'下月第一天'

  79: 

--简化  80: 

SELECT

DATEADD(MONTH

,DATEDIFF(MONTH

,0,@Date

)+1,0) AS

'下月第一天'

  81: 

--另一种当前月第一天算法  82: 

SELECT

DATEADD(MONTH

,1,DATEADD(DAY

,1-DATEPART(DAY

,@Date

),@Date

)) '下月第一天'

  83: 

GO

  84: 

  85: 

--计算给定日期所在月的下月最后一天  86: 

DECLARE

@Date

  DATETIME  87: 

SET

@Date

=GETDATE()  88: 

--当前月第一天加2个月再减去1天  89: 

SELECT

DATEADD(DAY

,-1,DATEADD(MONTH

,2,DATEADD(MONTH

,DATEDIFF(MONTH

,0,@Date

),0))) AS

'下月最后一天'

  90: 

--简化  91: 

SELECT

DATEADD(DAY

,-1,DATEADD(MONTH

,DATEDIFF(MONTH

,0,@Date

)+2,0)) AS

'下月最后一天'

  92: 

SELECT

DATEADD(MONTH

,DATEDIFF(MONTH

,0,@Date

)+2,0)-1 AS

'下月最后一天'

  93: 

--另一种算法  94: 

SELECT

DATEADD(MONTH

,DATEDIFF(MONTH

,-1,@Date

)+1,-1) '下月最后一天'

  95: 

--另一种当前月第一天算法  96: 

SELECT

DATEADD(DAY

,-1,DATEADD(MONTH

,2,DATEADD(DAY

,1-DATEPART(DAY

,@Date

),@Date

))) '下月最后一天'

  97: 

GO

  98: 

  99: 

--所在星期的第一天,计算给定日期所在星期的第1天(星期日为第一天)  100: 

DECLARE

@Date

  DATETIME  101: 

SET

@Date

= GETDATE()  102: 

--与SQL Server语言版本相关的算法  103: 

--思路:当前日期+星期日(每周的第1天)与当前日期的差的天数  104: 

--DATEPART(WEEKDAY,DATE

)的返回值与@@DATEFIRST相关  105: 

SET

DATEFIRST 7 -- 或者设置为美国英语SET LANGUAGE us_english; (星期日为第一天)

106: 

SELECT

DATEADD(WEEKDAY,1-DATEPART(WEEKDAY,@Date

),@Date

) AS

'所在星期的第一天,星期日'

  107: 

--星期日,与SQL Server语言版本或@@DATEFIRST无关  108: 

--'1989-12-31'

是星期日,'1989-12-31'

再加上(当前日期与1989-12-31差的星期数)个星期  109: 

SELECT

DATEADD(WEEK,DATEDIFF(WEEK,-1,@Date

),-1) AS

'所在星期的星期日'

  110: 

--或者  111: 

SELECT

DATEADD(WEEK,DATEDIFF(WEEK,6,@Date

),6) AS

'所在星期的星期日'

  112: 

GO

  113: 

  114: 

  115: 

--所在星期的第二天,计算给定日期所在星期的第2天(星期日为第一天)  116: 

DECLARE

@Date

  DATETIME  117: 

SET

@Date

= GETDATE()  118: 

--思路:当前日期+星期一(每周的第2天)与当前日期的差的天数  119: 

--DATEPART(WEEKDAY,DATE

)的返回值与@@DATEFIRST相关  120: 

SET

DATEFIRST 7 -- 或者设置为美国英语SET LANGUAGE us_english; (星期日为第一天)

121: 

SELECT

DATEADD(DAY

,2-DATEPART(WEEKDAY,@Date

),@Date

) AS

'所在星期的第二天,星期一'

  122: 

--星期一,与SQL Server语言版本或@@DATEFIRST无关  123: 

--'1900-01-01'

是星期一,'1900-01-01'

再加上(当前日期与1900-01-01差的星期数)个星期  124: 

SELECT

DATEADD(WEEK,DATEDIFF(WEEK,0,@Date

),0) AS

'所在星期的星期一'

  125: 

GO

  126: 

  127: 

--上个星期第一天,计算给定日期所在星期的上一个星期日(星期日为第一天)  128: 

DECLARE

@Date

  DATETIME  129: 

SET

@Date

= GETDATE()  130: 

--思路:当前日志所在星期的星期日再减1周  131: 

--DATEPART(WEEKDAY,DATE

)的返回值与@@DATEFIRST相关  132: 

SET

DATEFIRST 7 -- 或者设置为美国英语SET LANGUAGE us_english; (星期日为第一天)

133: 

SELECT

DATEADD(WEEK,-1,DATEADD(DAY

,1-DATEPART(WEEKDAY,@Date

),@Date

)) AS

'上个星期第一天,星期日'

  134: 

--一周等于7天  135: 

SELECT

DATEADD(DAY

,-7,DATEADD(DAY

,1-DATEPART(WEEKDAY,@Date

),@Date

)) AS

'上个星期第一天,星期日'

  136: 

--简化  137: 

SELECT

DATEADD(DAY

,-6-DATEPART(WEEKDAY,@Date

),@Date

) AS

'上个星期第一天,星期日'

  138: 

--上个星期日,与SQL Server语言版本或@@DATEFIRST无关  139: 

SELECT

DATEADD(WEEK,-1+DATEDIFF(WEEK,-1,@Date

),-1) AS

'上个星期日'

  140: 

--或者  141: 

SELECT

DATEADD(WEEK,DATEDIFF(WEEK,6,@Date

),-1) AS

'上个星期日'

  142: 

GO

  143: 

  144: 

  145: 

--下个星期第一天,计算给定日期所在星期的下一个星期日(星期日为第一天)  146: 

DECLARE

@Date

  DATETIME  147: 

SET

@Date

= GETDATE()  148: 

--思路:当前日志所在星期的星期日再加1周  149: 

--DATEPART(WEEKDAY,DATE

)的返回值与@@DATEFIRST相关  150: 

SET

DATEFIRST 7 -- 或者设置为美国英语SET LANGUAGE us_english; (星期日为第一天)

151: 

SELECT

DATEADD(WEEK,1,DATEADD(DAY

,1-DATEPART(WEEKDAY,@Date

),@Date

)) AS

'下个星期第一天,星期日'

  152: 

--一周等于7天  153: 

SELECT

DATEADD(DAY

,7,DATEADD(DAY

,1-DATEPART(WEEKDAY,@Date

),@Date

)) AS

'下个星期第一天,星期日'

  154: 

--简化  155: 

SELECT

DATEADD(DAY

,8-DATEPART(WEEKDAY,@Date

),@Date

) AS

'下个星期第一天,星期日'

  156: 

--下个星期日,与SQL Server语言版本或@@DATEFIRST无关  157: 

SELECT

DATEADD(WEEK,1+DATEDIFF(WEEK,-1,@Date

),-1) AS

'下个星期日'

  158: 

--或者  159: 

SELECT

DATEADD(WEEK,DATEDIFF(WEEK,-1,@Date

),6) AS

'下个星期日'

  160: 

GO

  161: 

  162: 

--判断给定日期是星期几  163: 

DECLARE

@Date

  DATETIME  164: 

SET

@Date

= GETDATE()  165: 

--DATEPART(WEEKDAY,DATE

)的返回值与@@DATEFIRST相关  166: 

SET

DATEFIRST 7 -- 或者设置为美国英语SET LANGUAGE us_english; (星期日为第一天)

167: 

SELECT

DATEPART(WEEKDAY,@Date

) --返回值 1-星期日,2-星期一,3-星期二......7-星期六  168: 

--上面算法与SQL 语言版本或 @@DATEFIRST

相关  169: 

--下面算法与SQL Server语言版本或@@DATEFIRST无关  170: 

SELECT

DATENAME(WEEKDAY,@Date

) '星期'

  171: 

GO

  172: 

  173: 

  174: 

--年度计算  175: 

DECLARE

@Date

  DATETIME  176: 

SET

@Date

=GETDATE()  177: 

--年初,计算给定日期所在年的第一天  178: 

SELECT

DATEADD(YEAR

,DATEDIFF(YEAR

,0,@Date

),0) AS

'所在年的第一天'

  179: 

--年末,计算给定日期所在年的最后一天  180: 

SELECT

DATEADD(YEAR

,DATEDIFF(YEAR

,-1,@Date

),-1) AS

'所在年的最后一天'

  181: 

--上一年年初,计算给定日期所在年的上一年的第一天  182: 

SELECT

DATEADD(YEAR

,DATEDIFF(YEAR

,-0,@Date

)-1,0) AS

'所在年的上一年的第一天'

  183: 

--上一年年末,计算给定日期所在年的上一年的最后一天  184: 

SELECT

DATEADD(YEAR

,DATEDIFF(YEAR

,0,@Date

),-1) AS

'所在年的上一年的最后一天'

  185: 

--下一年年初,计算给定日期所在年的下一年的第一天  186: 

SELECT

DATEADD(YEAR

,1+DATEDIFF(YEAR

,0,@Date

),0) AS

'所在年的下一年的第一天'

  187: 

--下一年年末,计算给定日期所在年的下一年的最后一天  188: 

SELECT

DATEADD(YEAR

,1+DATEDIFF(YEAR

,-1,@Date

),-1) AS

'所在年的下一年的最后一天'

  189: 

GO

  190: 

  191: 

--季度计算  192: 

DECLARE

@Date

  DATETIME  193: 

SET

@Date

=GETDATE()  194: 

--季度初,计算给定日期所在季度的第一天  195: 

SELECT

DATEADD(QUARTER,DATEDIFF(QUARTER,0,@Date

),0) AS

'当前季度的第一天'

  196: 

--季度末,计算给定日期所在季度的最后一天  197: 

SELECT

DATEADD(QUARTER,1+DATEDIFF(QUARTER,0,@Date

),-1) AS

'当前季度的最后一天'

  198: 

--上个季度初  199: 

SELECT

DATEADD(QUARTER,DATEDIFF(QUARTER,0,@Date

)-1,0) AS

'当前季度的上个季度初'

  200: 

--上个季度末  201: 

SELECT

DATEADD(QUARTER,DATEDIFF(QUARTER,0,@Date

),-1) AS

'当前季度的上个季度末'

  202: 

--下个季度初  203: 

SELECT

DATEADD(QUARTER,1+DATEDIFF(QUARTER,0,@Date

),0) AS

'当前季度的下个季度初'

  204: 

--下个季度末  205: 

SELECT

DATEADD(QUARTER,2+DATEDIFF(QUARTER,0,@Date

),-1) AS

'当前季度的下个季度末'

  206: 

GO

  207: 

  208: 

--计算给定日期所在月的天数  209: 

DECLARE

@Date

DATETIME;  210: 

SET

@Date

= GETDATE()  211: 

--本月度第一天与下月度第一天所差的天数  212: 

SELECT

DATEDIFF(DAY

,DATEADD(MONTH

,DATEDIFF(MONTH

,0,@Date

),0),DATEADD(MONTH

,1+DATEDIFF(MONTH

,0,@Date

),0))  213: 

--借助变量简化  214: 

SELECT

@Date

= DATEADD(MONTH

,DATEDIFF(MONTH

,0,@Date

),0) --本月度第一天  215: 

SELECT

DATEDIFF(DAY

,@Date

,DATEADD(MONTH

,1,@Date

))  216: 

--另一种思路:给定月最后一天的日期,记为本月天数  217: 

SELECT

DAY

(DATEADD(MONTH

,DATEDIFF(MONTH

,-1,@Date

),-1))  218: 

GO

  219: 

  220: 

--计算给定日期所在季度的天数  221: 

DECLARE

@Date

DATETIME;  222: 

SET

@Date

= GETDATE()  223: 

--本季度第一天与下季度第一天所差的天数  224: 

SELECT

DATEDIFF(DAY

,DATEADD(QUARTER,DATEDIFF(QUARTER,0,@Date

),0),DATEADD(QUARTER,1+DATEDIFF(QUARTER,0,@Date

),0))  225: 

--借助变量简化  226: 

SELECT

@Date

= DATEADD(QUARTER,DATEDIFF(QUARTER,0,@Date

),0) --本季度第一天  227: 

SELECT

DATEDIFF(DAY

,@Date

,DATEADD(QUARTER,1,@Date

))  228: 

GO

  229: 

  230: 

--计算给定日期所在年度的天数  231: 

DECLARE

@Date

DATETIME;  232: 

SET

@Date

= GETDATE()  233: 

--本年度第一天与下年度第一天所差的天数  234: 

SELECT

DATEDIFF(DAY

,DATEADD(YEAR

,DATEDIFF(YEAR

,0,@Date

),0),DATEADD(YEAR

,1+DATEDIFF(YEAR

,0,@Date

),0))  235: 

--借助变量简化  236: 

SELECT

@Date

= DATEADD(YEAR

,DATEDIFF(YEAR

,0,@Date

),0) --本年度第一天  237: 

SELECT

DATEDIFF(DAY

,@Date

,DATEADD(YEAR

,1,@Date

))  238: 

GO

  239: 

  240: 

--判断给定日期所在年是否闰年  241: 

--根据全年总天数判断  242: 

DECLARE

@Date

DATETIME;  243: 

SET

@Date

= GETDATE()  244: 

SELECT

CASE

DATEDIFF(DAY

,DATEADD(YEAR

,DATEDIFF(YEAR

,0,@Date

),0),DATEADD(YEAR

,1+DATEDIFF(YEAR

,0,@Date

),0))  245: 

  WHEN

365 THEN

'平年'

ELSE

'闰年'

END

  246: 

--根据二月天数判断  247: 

--给日期的上一年最后一天加2个月,即为当年2月最后一天  248: 

SELECT

CASE

DAY

(DATEADD(MONTH

,2,DATEADD(YEAR

,DATEDIFF(YEAR

,0,@Date

),-1))) WHEN

28 THEN

'平年'

ELSE

'闰年'

END

  249: 

GO

  250: 

  251: 

--计算给定日期是当年的第几天  252: 

DECLARE

@Date

DATETIME;  253: 

SET

@Date

= GETDATE()  254: 

SELECT

DATEPART(DAYOFYEAR,@Date

) [DayOfYear];  255: 

SELECT

DATENAME(DAYOFYEAR,@Date

)  [DayOfYear];  256: 

--另一种思路:当前日期与上年最后一天差的天数  257: 

SELECT

DATEDIFF(DAY

,DATEADD(YEAR

,DATEDIFF(YEAR

,0,@Date

),-1),@Date

)[DayOfYear]  258: 

GO

  259: 

  260: 

--计算给定日期是当年的第几周  261: 

DECLARE

@Date

DATETIME;  262: 

SET

@Date

= GETDATE()  263: 

SELECT

DATEPART(WEEK,@Date

) [WeekOfYear]; --返回int型  264: 

SELECT

DATENAME(WEEK,@Date

) [WeekOfYear]; --返回varchar型  265: 

GO

  266: 

  267: 

--计算给定日期是当年的第几月  268: 

DECLARE

@Date

DATETIME;  269: 

SET

@Date

= GETDATE()  270: 

SELECT

DATEPART(MONTH

,@Date

) [MonthOfYear]; --返回int型  271: 

SELECT

DATENAME(MONTH

,@Date

) [MonthOfYear]; --返回varchar型  272: 

SELECT

MONTH

(@Date

) [MonthOfYear];--返回int型  273: 

GO

  274: 

  275: 

--计算给定日期是当年的第几季度  276: 

DECLARE

@Date

DATETIME;  277: 

SET

@Date

= GETDATE()  278: 

SELECT

DATEPART(QUARTER,@Date

) [QuarterOfYear]; --返回int型  279: 

SELECT

DATENAME(QUARTER,@Date

) [QuarterOfYear]; --返回varchar型  280: 

GO

  281: 

  282: 

--计算给定日期是当月的第几周  283: 

DECLARE

@Date

DATETIME;  284: 

SET

@Date

= GETDATE()  285: 

--思路,给定日期是当年的第几周-给定日期所在月第一天是当年的第几周  286: 

SELECT

DATEPART(WEEK,@Date

)-DATEPART(WEEK,DATEADD(MONTH

,DATEDIFF(MONTH

,0,@Date

),0))+1 [WeekOfMonth]  287: 

SELECT

DATEPART(WEEK,@Date

)-DATEPART(WEEK,DATEADD(DAY

,1-DATEPART(DAY

,@Date

),@Date

))+1 [WeekOfMonth]  288: 

GO

  289: 

  290: 

--计算给定日期所在月的第一个星期一是哪天  291: 

DECLARE

@Date

DATETIME;  292: 

SET

@Date

= GETDATE()  293: 

--思路,1900-01-01(星期一)加上(给定日志所在月的月6号与1900-01-01差的周数)个周  294: 

--为什么不选7号?如果是7号,那么7好恰好是星期日的话,第一个周一就会算到8号。  295: 

--为什么不选5号?如果5号是星期六,那么周一就跑到上月了。小于5号与这个道理一样。  296: 

SELECT

DATEADD(WEEK,DATEDIFF(WEEK,0,DATEADD(DAY

,6-DATEPART(DAY

,@Date

),@Date

)),0) '所在月的第一个星期一'

  297: 

SELECT

DATEADD(WEEK,DATEDIFF(WEEK,0,DATEADD(DAY

,6-DATEPART(DAY

,@Date

),@Date

)),7) '所在月的第二个星期一'

  298: 

SELECT

DATEADD(WEEK,DATEDIFF(WEEK,0,DATEADD(DAY

,6-DATEPART(DAY

,@Date

),@Date

)),1) '所在月的第一个星期二'

  299: 

SELECT

DATEADD(WEEK,DATEDIFF(WEEK,0,DATEADD(DAY

,6-DATEPART(DAY

,@Date

),@Date

)),8) '所在月的第二个星期二'

  300: 

GO

标签:SQL,SELECT,时间算法,MONTH,DAY

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值