【问题标题】:Date difference (in years) incl. year fraction日期差异(年)包括。年分数
【发布时间】:2012-08-06 09:08:00
【问题描述】:

有没有一种简单的方法来计算两个日期之间的差异:

  1. 表示为年数,包括。年份分数;和
  2. 考虑闰年?

例如,2011 年 3 月 1 日和 2012 年 3 月 1 日之间的差值为 1 年。但是,如果我使用 DATEDIFF(day,..,..) 并除以 365,由于闰年,我会得到 1.00274 的(不受欢迎的)答案。

需要明确的是,我还需要任何年份的分数(即,不仅仅是年数)。例如,2011 年 3 月 1 日和 2012 年 3 月 3 日之间的差异是 1.005479(1 年 + 2/365 年)。 2011 年 3 月 1 日和 2012 年 2 月 29 日之间的差异是 0.997268(0 年 + 365/366 年)

因此,总而言之,上述两个示例的输出(以 DECIMAL(7,6) 为单位)将是:

1.000000 1.005479 0.997268

【问题讨论】:

  • 你能告诉我你想要在上面的例子中输出什么吗?
  • 也许这会有所帮助:stackoverflow.com/questions/8882667/…
  • 但是“年分数”应该如何定义(据我所知,这不是一个众所周知的术语)?根据具体日期,您可能需要将一年计算为 366 天而不是 365 天。例如2011 年 3 月 1 日和 2012 年 2 月 29 日之间的差异的预期输出是多少?
  • 您能否给出 29/02/2012 和 28/02/2013 之间的差异的预期输出,以及 29/02/2012 和 01/03/2013 之间的差异?
  • 我在您发布的同时编辑了我的帖子。我希望年份分数中的分母是来年的天数。哪一个,现在我想起来,有点回答我的问题(除了有一个内置的 T-SQL 函数可以做到这一点)。

标签: sql sql-server-2008 tsql


【解决方案1】:
DECLARE @FromDate DATETIME = '2019-02-28', @ToDate DATETIME = '2020-02-26',
@diff_year_temp int, @diff_year int,@diff_year_frac float,@ToDateDays float,@FromDateDays float,@y_to int,@y_from int,@diff float,
@FromDec float,@JanTo float,@JanToFrac float,@FromDecFrac float,@ToDateplusone datetime,@FromplusToyear datetime

set @diff_year_temp=datediff(year,@FromDate,@ToDate)
set @FromplusToyear=case when DATEPART(day,@FromDate)=29 and datepart(month,@FromDate)=2 then dateadd(day,1,dateadd(year,@diff_year_temp,@FromDate)) else  dateadd(year,@diff_year_temp,@FromDate) end
set @ToDateplusone=dateadd(day,1,@ToDate)
set @y_to = datepart(year,@ToDate)
set @y_from=datepart(year,@FromDate)
set @FromDec=datediff(day,@FromDate,cast(CONCAT(@y_from,'-12-31') as date))+1
set @JanTo=datediff(day,cast(CONCAT(@y_to,'-01-01') as date),@ToDate)+1
set @ToDateDays = DATEDIFF(day,  cast(@y_to as char(4)),  cast(@y_to+1 as char(4))) 
set @FromDateDays = DATEDIFF(day,  cast(@y_from as char(4)),  cast(@y_from+1 as char(4)))

set @FromDecFrac=@FromDec/@FromDateDays
set @JanToFrac=@JanTo/@ToDateDays
set @diff_year=case when @ToDateplusone >= @FromplusToyear  then @diff_year_temp else @diff_year_temp-1 end
set @diff_year_frac=case when @ToDateplusone >= @FromplusToyear then datediff(day,@FromplusToyear,@ToDateplusone)/@ToDateDays  else  @JanToFrac+@FromDecFrac end
set @diff=@diff_year+@diff_year_frac

select @diff

【讨论】:

    【解决方案2】:

    试试这个:

       DECLARE @stdate datetime,@eddate datetime
        SET @stdate='2007-02-01'
        SET @eddate='2012-03-03'
    
        ;WITH CTE as (
        select DATEDIFF(yy,@stdate,convert(datetime,cast(DATEPART(year,@eddate) as varchar)+'-'+cast(DATEPART(month,@stdate) as varchar)+'-'+cast(DATEPART(dd,@stdate) as varchar))) yrs,
        DATEDIFF(dd,convert(datetime,cast(DATEPART(year,@eddate) as varchar)+'-'+cast(DATEPART(month,@stdate) as varchar)+'-'+cast(DATEPART(dd,@stdate) as varchar)),@eddate) as dayss,
        CAST(CASE WHEN DATEPART(dd,DATEADD(mm,datediff(mm,-1,(convert(datetime,cast(DATEPART(year,@eddate) as varchar)+'-'+cast(DATEPART(month,@stdate) as varchar)+'-'+cast(DATEPART(dd,@stdate) as varchar)))),-1)) = 29 then 366 else 365 end as float) as ydays
        )
        select yrs+dayss/cast(ydays as float) from CTE
    

    【讨论】:

      【解决方案3】:

      这是一个查询。但是您的示例中有一个逻辑错误。我认为“2011 年 3 月 1 日和 2012 年 3 月 3 日之间的差异是 1.005479(1 年 + 2/365 年)”应该是(1 年 + 2/366 年),因为 2011 年 3 月 3 日和 2012 年 3 月 3 日之间的 29.02.2012 所以在去年 366 天。

          Declare @BDate datetime
          Declare @EDate datetime
          SET @BDate='2011-03-01'
          SET @EDate='2012-02-29'
      
          select 
      
          datediff(year,@BDate,@Edate)- 
          case when dateadd(year,datediff(year,@BDate,@Edate),@BDate)>@Edate then 1 else 0 end 
          +cast(datediff(day,dateadd(year,datediff(year,@BDate,@Edate)-
          case when dateadd(year,datediff(year,@BDate,@Edate),@BDate)>@Edate then 1 else 0 end   ,@BDate),@Edate) as float)/
      cast(datediff(day,dateadd(year,-1,@Edate),@Edate) as float)
      

      【讨论】:

      • 这在大多数情况下都有效,但在“2011-12-31”和“2012-01-01”上失败。我在投票后注意到了这一点
      • 谢谢。是的,我确实需要重新考虑我的逻辑。
      • @t-clausen.dk 我已经解决了这个问题尝试新版本。
      【解决方案4】:

      我认为这行得通(希望我选择了你可以关注的名字):

      declare @StartTime datetime
      declare @EndTime datetime
      
      select @StartTime = '20110301',@EndTime = '20120303'
      
      select YearsDiffNorm + ((DaysIntoYear * 1.0) / (DaysIntoYear + DaysRemainingInYear))
      from (
      select
          YearsDiffNorm,
          DATEDIFF(day,DATEADD(YEAR,YearsDiffNorm,@StartTime),@EndTime) as DaysIntoYear,
          DATEDIFF(day,@EndTime,DATEADD(YEAR,YearsDiffNorm+1,@StartTime)) as DaysRemainingInYear
      from (
      select CASE WHEN DATEADD(year,YearsDiff,@StartTime) > @EndTime then YearsDiff - 1 else YearsDiff END as YearsDiffNorm
      from (
          select DATEDIFF(year,@StartTime,@EndTime) as YearsDiff
      ) t
      ) t2
      ) t3
      

      【讨论】:

        【解决方案5】:

        试试这个,

        SELECT Cast(DateDiff(yyyy, '2011-03-01', '2012-03-01') As VARCHAR) + 'Yer : '
        + Cast(DateDiff(mm, '2011-03-01', '2012-03-01') As VARCHAR) + 'Mon : '
        + Cast(DateDiff(dd, '2011-03-01', '2012-03-01') As VARCHAR) + 'Dte'
        

        希望对你有帮助,谢谢。

        【讨论】:

        • 谢谢,但这不是我想要的。我应该在我的帖子中更加明确,我将对其进行编辑。我想要任何年份的分数以及整数年数。
        猜你喜欢
        • 2021-03-11
        • 2021-05-06
        • 2011-12-18
        • 2018-04-13
        • 1970-01-01
        • 2018-04-24
        • 1970-01-01
        • 2016-07-10
        • 1970-01-01
        相关资源
        最近更新 更多