我正在尝试根据用户输入的年、月、日来计算出生日期。
下面的示例将给出我到底想要实现的目标的一些想法。
基本上有两个步骤
1 ) 获取从出生日期算起的天/月和年(用户输入的日期)。例如 04 Feb 1988 应返回 29 年 8 个月 28 天
2 ) 从输入的日/月和年中获取日期。例如 29 年 8 个月零 28 天应该返回 04 Feb 1988
步骤 1 工作正常,但对于情况 2,当年份是闰年且月份是二月时,我遇到问题。
我已经花了一天半的时间寻找解决方案,但没有用,因为它们只对情况 1 有帮助。
我还尝试计算当前日期和以年份为 365.25 的出生日期之间的总天数,然后从当前日期中减去它,但面临同样的问题。
最佳答案
如果您对 TVF 持开放态度,我有一个函数可以计算耗时(以年、月、日、小时、分钟和秒为单位)。您可以删除(或忽略)小时、分钟和秒
现在,我从未考虑过解决相反的问题,但可以使用相同的函数来完成。
这个函数非常准确且高效。您永远不必担心各种日期计算。
在下面的示例中,我使用了今天的日期 2017-11-01,但您可以替换为 GetDate()
示例 1
Declare @Date date = '1988-02-04'
Select * from [dbo].[tvf-Date-Elapsed](@Date,'2017-11-01')
返回
Years Months Days Hours Minutes Seconds
29 8 28 0 0 0
示例 2
Declare @Y int = 29
Declare @M int = 8
Declare @D int = 28
Select D=max(D)
From (
Select Top (500) D= DateAdd(DAY,-1+Row_Number() over (Order by (Select NULL)), DateAdd(DAY,((@Y*366)+(@M*31)+@D)*-1,'2017-11-01'))
From master..spt_values n1
) A
Cross Apply [dbo].[tvf-Date-Elapsed](A.D,'2017-11-01')
Where Years =@Y
and Months=IIF(@M=0,Months,@M)
and Days =IIF(@D=0,Days,@D)
返回
D
1988-02-04 00:00:00.000
如果有兴趣的话,UDF
CREATE FUNCTION [dbo].[tvf-Date-Elapsed] (@D1 DateTime,@D2 DateTime)
Returns Table
Return (
with cteBN(N) as (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cteRN(R) as (Select Row_Number() Over (Order By (Select NULL))-1 From cteBN a,cteBN b,cteBN c),
cteYY(N,D) as (Select Max(R),Max(DateAdd(YY,R,@D1))From cteRN R Where DateAdd(YY,R,@D1)<=@D2),
cteMM(N,D) as (Select Max(R),Max(DateAdd(MM,R,D)) From (Select Top 12 R From cteRN Order By 1) R, cteYY P Where DateAdd(MM,R,D)<=@D2),
cteDD(N,D) as (Select Max(R),Max(DateAdd(DD,R,D)) From (Select Top 31 R From cteRN Order By 1) R, cteMM P Where DateAdd(DD,R,D)<=@D2),
cteHH(N,D) as (Select Max(R),Max(DateAdd(HH,R,D)) From (Select Top 24 R From cteRN Order By 1) R, cteDD P Where DateAdd(HH,R,D)<=@D2),
cteMI(N,D) as (Select Max(R),Max(DateAdd(MI,R,D)) From (Select Top 60 R From cteRN Order By 1) R, cteHH P Where DateAdd(MI,R,D)<=@D2),
cteSS(N,D) as (Select Max(R),Max(DateAdd(SS,R,D)) From (Select Top 60 R From cteRN Order By 1) R, cteMI P Where DateAdd(SS,R,D)<=@D2)
Select [Years] = cteYY.N
,[Months] = cteMM.N
,[Days] = cteDD.N
,[Hours] = cteHH.N
,[Minutes] = cteMI.N
,[Seconds] = cteSS.N
--,[Elapsed] = Format(cteYY.N,'0000')+':'+Format(cteMM.N,'00')+':'+Format(cteDD.N,'00')+' '+Format(cteHH.N,'00')+':'+Format(cteMI.N,'00')+':'+Format(cteSS.N,'00')
From cteYY,cteMM,cteDD,cteHH,cteMI,cteSS
)
--Max 1000 years
--Select * from [dbo].[tvf-Date-Elapsed] ('1991-09-12 21:00:00.000',GetDate())
--Select * from [dbo].[tvf-Date-Elapsed] ('2017-01-01 20:30:15','2018-02-05 22:58:35')
关于sql-server - 使用sql中的日期函数获取天/月/年之前的过去日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47060427/