一、日期推算
1--指定日期该年的第一天或最后一天
年的第一天
SELECT CONVERT(char(5),@dt,120)+'1-1'
年的最后一天
SELECT CONVERT(char(5),120)+'12-31'
2--指定日期所在季度的第一天或最后一天
季度的第一天
SELECT CONVERT(datetime,
CONVERT(char(8),
DATEADD(Month,
DATEPART(Quarter,@dt)*3-Month(@dt)-2,
@dt),
120)+'1')
季度的最后一天(CASE判断法)
SELECT CONVERT(datetime,@dt)*3-Month(@dt),
120)
+CASE WHEN DATEPART(Quarter,@dt) in(1,4)
THEN '31'ELSE '30' END)
季度的最后一天(直接推算法)
SELECT DATEADD(Day,-1,
1+DATEPART(Quarter,
120)+'1')
3--指定日期所在月份的第一天或最后一天
月的第一天
SELECT CONVERT(datetime,CONVERT(char(8),120)+'1')
月的最后一天
SELECT DATEADD(Day,DATEADD(Month,1,@dt),120)+'1')
月的最后一天(容易使用的错误方法)
SELECT DATEADD(Month,DATEADD(Day,-DAY(@dt),@dt))
4--指定日期所在周的任意一天
SELECT DATEADD(Day,@number-DATEPART(Weekday,@dt)
5--指定日期所在周的任意星期几
星期天做为一周的第1天
SELECT DATEADD(Day,@number-(DATEPART(Weekday,@dt)+@@DATEFirsT-1)%7,@dt)
星期一做为一周的第1天
SELECT DATEADD(Day,@dt)+@@DATEFirsT-2)%7-1,@dt)
二、特殊日期
--特殊日期加减函数
对于日期指定部分的加减,使用DATEADD函数就可以轻松实现。
在实际的处理中,还有一种比较另类的日期加减处理
就是在指定的日期中,加上(或者减去)多个日期部分
比如将2005年3月11日,加上1年3个月11天2小时。
对于这种日期的加减处理,DATEADD函数的力量就显得有点不够。
本函数实现这样格式的日期字符串加减处理:
y-m-d h:m:s.m | -y-m-d h:m:s.m
说明:
要加减的日期字符输入方式与日期字符串相同。日期与时间部分用空格分隔
最前面一个字符如果是减号(-)的话,表示做减法处理,否则做加法处理。
如果日期字符只包含数字,则视为日期字符中,仅包含天的信息。
CREATE FUNCTION dbo.f_DateADD(
@Date datetime,
@DateStr varchar(23)
)RETURNS datetime
AS
BEGIN
DECLARE @bz int,@s varchar(12),@i int
IF @DateStr IS NULL OR @Date IS NULL
OR(CHARINDEX('.',@DateStr)>0
AND @DateStr NOT LIKE '%[:]%[:]%.%')
RETURN(NULL)
IF @DateStr='' RETURN(@Date)
SELECT @bz=CASE
WHEN LEFT(@DateStr,1)='-' THEN -1
ELSE 1 END,
@DateStr=CASE
WHEN LEFT(@Date,1)='-'
THEN STUFF(RTRIM(LTRIM(@DateStr)),'')
ELSE RTRIM(LTRIM(@DateStr)) END
IF CHARINDEX(' ',@DateStr)>1
OR CHARINDEX('-',@DateStr)>1
OR(CHARINDEX('.',@DateStr)=0
AND CHARINDEX(':',@DateStr)=0)
BEGIN
SELECT @i=CHARINDEX(' ',@DateStr+' ')
,@s=REVERSE(LEFT(@DateStr,@i-1))+'-'
,@DateStr=STUFF(@DateStr,@i,'')
,@i=0
WHILE @s>'' and @i<3
SELECT @Date=CASE @i
WHEN 0 THEN DATEADD(Day,@bz*REVERSE(LEFT(@s,CHARINDEX('-',@s)-1)),@Date)
WHEN 1 THEN DATEADD(Month,@Date)
WHEN 2 THEN DATEADD(Year,@Date)
END,
@s=STUFF(@s,@s),''),
@i=@i+1
END
IF @DateStr>''
BEGIN
IF CHARINDEX('.',@DateStr)>0
SELECT @Date=DATEADD(Millisecond
,@bz*STUFF(@DateStr,CHARINDEX('.',@DateStr),
@Date),
@DateStr=LEFT(@DateStr,@DateStr)-1)+':',
@i=0
ELSE
SELECT @DateStr=@DateStr+':',@i=0
WHILE @DateStr>'' and @i<3
SELECT @Date=CASE @i
WHEN 0 THEN DATEADD(Hour,@bz*LEFT(@DateStr,CHARINDEX(':',@DateStr)-1),@Date)
WHEN 1 THEN DATEADD(Minute,@Date)
WHEN 2 THEN DATEADD(Second,
@DateStr=STUFF(@DateStr,
@i=@i+1
END
RETURN(@Date)
END
GO
三、计算工作时间
1--定义工作时间表
CREATE TABLE tb_worktime(
ID int identity(1,1) PRIMARY KEY, --序号
time_start smalldatetime, --工作的开始时间
time_end smalldatetime, --工作的结束时间
worktime AS DATEDIFF(Minute,time_start,time_end) --工作时数(分钟)
)
GO
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_WorkTime]') and xtype in (N'FN',N'IF',N'TF'))
drop function [dbo].[f_WorkTime]
GO
2--计算两个日期之间的工作时间 CREATE FUNCTION f_WorkTime( @date_begin datetime, --计算的开始时间 @date_end datetime --计算的结束时间 )RETURNS int AS BEGIN DECLARE @worktime int IF DATEDIFF(Day,@date_begin,@date_end)=0 SELECT @worktime=SUM(DATEDIFF(Minute, CASE WHEN CONVERT(VARCHAR,108)>time_start THEN CONVERT(VARCHAR,108) ELSE time_start END,@date_end,108)<time_end THEN CONVERT(VARCHAR,108) ELSE time_end END)) FROM tb_worktime WHERE time_end>CONVERT(VARCHAR,108) AND time_start<CONVERT(VARCHAR,108) ELSE SET @worktime =(SELECT SUM(CASE WHEN CONVERT(VARCHAR,108)>time_start THEN DATEDIFF(Minute,CONVERT(VARCHAR,108),time_end) ELSE worktime END) FROM tb_worktime WHERE time_end>CONVERT(VARCHAR,108)) +(SELECT SUM(CASE WHEN CONVERT(VARCHAR,108)<time_end THEN DATEDIFF(Minute,108)) ELSE worktime END) FROM tb_worktime WHERE time_start<CONVERT(VARCHAR,108)) +CASE WHEN DATEDIFF(Day,@date_end)>1 THEN (DATEDIFF(Day,@date_end)-1) *(SELECT SUM(worktime) FROM tb_worktime) ELSE 0 END RETURN(@worktime) END
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。