简体   繁体   English

年月日格式中两个日期之间的年龄总和

[英]Sum of age between two dates in Years Month Days format

I need to calculate age in years, months and days format between two dates ( DateFrom and DateTo ) in a way that: 我需要以下列方式计算两个日期( DateFromDateTo )之间的年,月和日格式的年龄:

  • If day of month in DateFrom is 1st then take it as a whole month 如果DateFrom中的DateFrom一天是第1天,则将其作为整月使用
  • If day of month in DateFrom is not 1st then count days till the end of the month. 如果DateFrom中的DateFrom一天不是第一天,则计算直到月末的天数。

Example: 例:

  • DateFrom='2010-02-0 1 ', DateTo='2011-03-11', Age= 1 Years, 1 Months 11 Days DateFrom ='2010-02-0 1 ',DateTo ='2011-03-11',年龄= 1年,1个月11
  • DateFrom='2010-02-0 2 ', DateTo='2011-03-11', Age= 1 Years, 1 Months 8 Days DateFrom ='2010-02-0 2 ',DateTo ='2011-03-11',年龄= 1年,1个月8

After calculating the age I'd need to sum the ages assuming that month is 30 days - in the above example I'd expect result: 2 Years, 2 Months, 19 Days. 在计算年龄之后,我需要将年龄相加,假设月份是30天 - 在上面的例子中,我期望结果:2年,2个月,19天。

My assumption would be that you have have a table containing " DateFrom " and " DateTo " columns so the query would be something like this: 我的假设是你有一个包含“ DateFrom ”和“ DateTo ”列的表,所以查询将是这样的:

DECLARE @TotalDiffInDays int = (SELECT AVG(DATEDIFF(DAY, DateFrom, DateTo)) AS [TotalDays] FROM #t)
SELECT @TotalDiffInDays
DECLARE @DaysInMonth int = 30;
DECLARE @DaysInYear int = 365;

SELECT 
    @TotalDiffInDays / 365 AS AvgYearsDiff, 
    (@TotalDiffInDays / @DaysInMonth  - @TotalDiffInDays / @DaysInYear * 12) AS AvgMonthsDiff,
    @TotalDiffInDays - ((@TotalDiffInDays / 365) * @DaysInYear + (@TotalDiffInDays / @DaysInMonth  - @TotalDiffInDays / @DaysInYear * 12) * @DaysInMonth) AS AvgDaysDiff

Note that in this case I am using INT division to get correct numbers. 请注意,在这种情况下,我使用INT除法来获得正确的数字。

In addition, if you just want to get dates difference in the format you desribed above you can use this query: 此外,如果您只想以上面描述的格式获取日期差异,则可以使用此查询:

SELECT 
    DATEDIFF(YEAR, DateFrom, DateTo) AS [Years],
    -- Add year diff to get corret months diff 
    DATEDIFF(MONTH, DATEADD(YEAR, DATEDIFF(YEAR, DateFrom, DateTo), DateFrom), DateTo) AS [Months], 
    -- Add months diff to get correct days diff
    DATEDIFF(DAY, DATEADD(MONTH, DATEDIFF(MONTH, DateFrom, DateTo), DateFrom), DateTo) AS [Days]
FROM #t

I hope this will helps. 我希望这会有所帮助。

Yeah, just forgot about your rule of the 1st and not 1st day of the month, you can easily modify those queries with adding the DATEPART(DAY , your_date) function to check if it's a 1st date of the month and perform DETEADD() to apply this logic or just add a value of 1 before AVG. 是的,只是忘了你的第一天而不是一月的第一天的规则,你可以通过添加DATEPART(DAY,your_date)函数来轻松修改这些查询,以检查它是否是该月的第一个日期并执行DETEADD()应用此逻辑或只在AVG之前添加值1。

So basically since this custom date maths, you'd need to implement your own functions to get desired results. 所以基本上这个自定义日期数学,你需要实现自己的函数来获得所需的结果。

See the TSQL below 请参阅下面的TSQL

CREATE FUNCTION dbo.getDateSum(@d1 varchar(100),  @d2 varchar(100)) 
RETURNS varchar(100)
WITH EXECUTE AS CALLER
AS
BEGIN
    DECLARE @y int, @m int, @d int
    Select 
        @d1= REPLACE(REPLACE(REPLACE(@d1,' years, ', '-'),' months, ','-'),' days',''),
        @d2= REPLACE(REPLACE(REPLACE(@d2,' years, ', '-'),' months, ','-'),' days','')
    Select 
        @y= CAST(LEFT(@d1,CHARINDEX('-',@d1)-1) AS INT)+CAST(LEFT(@d2,CHARINDEX('-',@d2)-1) AS INT),
        @m= CAST(SUBSTRING(@d1,CHARINDEX('-',@d1)+1,LEN(@d1)-CHARINDEX('-',REVERSE(@d1))-CHARINDEX('-',@d1))AS INT)+CAST(SUBSTRING(@d2,CHARINDEX('-',@d2)+1,LEN(@d2)-CHARINDEX('-',REVERSE(@d2))-CHARINDEX('-',@d2)) AS INT),
        @d= CAST(LEFT(REVERSE(@d1),CHARINDEX('-',REVERSE(@d1))-1)AS INT)+CAST(LEFT(REVERSE(@d2),CHARINDEX('-',REVERSE(@d2))-1) AS INT)

    IF(@d>30)
    BEGIN
        SET @d=@d%30
        SET @m=@m+CAST(@d/30 as INT)
    END
    IF(@m>30)
    BEGIN
        SET @m=@m%12
        SET @y=@y+CAST(@m/12 as INT)
    END

    RETURN (cast(@y as varchar)+ ' years, ' + cast(@m as varchar) +' months, '+ cast(@d as varchar) + ' days' );
END
go


CREATE FUNCTION dbo.getDateDiff(@df date,  @dt date) 
RETURNS varchar(100)
WITH EXECUTE AS CALLER
AS
BEGIN
    declare @y int, @m int, @d int


    Select @y= YEAR(@dt)- YEAR(@df),@m= MONTH(@dt)- MONTH(@df),@d=CASE WHEN DAY(@df)=1 THEN DAY(@dt)- DAY(@df)+1 ELSE  DAY(@dt)- DAY(@df) -1 END
    If (@d<0) 
    BEGIN 
        Set @m=@m-1
        set @d=@d + DATEDIFF(d, @dt, EOMONTH(@dt))
    END
    IF(@m<0)
    BEGIN
        Set @y=@y-1
        Set @m=@m+ 12
    END

    RETURN (cast(@y as varchar)+ ' years, ' + cast(@m as varchar) +' months, '+ cast(@d as varchar) + ' days' )
END

go

SELECT dbo.getDateSum(dbo.getDateDiff('2010-02-01','2011-03-11'),dbo.getDateDiff('2010-02-02', '2011-03-11'))
go

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM