SQL Server时间算法总结(zhuan)
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: --下面算法课以保留时分秒 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

浙公网安备 33010602011771号