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