微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SqlServer教程—第二章日期处理二

一、日期推算

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] 举报,一经查实,本站将立刻删除。

相关推荐