【问题标题】:Double precision number of months between dates postgres日期之间的双精度月数 postgres
【发布时间】:2016-06-14 16:39:54
【问题描述】:

是否可以将两个日期之间的月数计算为双精度而不是整数?例如,2016-05-042015-03-21 之间的差异可能类似于 13.4213.43 个月?

【问题讨论】:

  • .42 或 .43 哪个个月?
  • 我不太在意,可能是 30 天或 31 天或 29 天或 28 天中的 13 天。只要它是整数个月 + 大约一个月的数量的大约分数我'我很满意。

标签: postgresql timestamp double date-difference


【解决方案1】:

有很多方法可以计算类似的东西,并且根据您用于计算的规则,您会得到不同的结果。

以下方式为您在两个日期之间的给定时间段内提供一年的 12 日数:

select (date'2016-05-04' - date'2015-03-21') / 365.0 * 12

以上结果为 13.48。

以下方法给出了一个可能更准确的数字 (13.47),尽管要复杂得多,并且产生的差异很小:

select extract('years' from age) * 12 + extract('months' from age) + extract('days' from age) / 30
from (select age('2016-05-04'::timestamp, '2015-03-21'::timestamp)) a

【讨论】:

    【解决方案2】:

    对于那些对精确计算感兴趣的人,我写了以下函数来计算两个日期之间的月差,包括小数部分:

    CREATE FUNCTION
      MONTH_FRACTION(
          from_date DATE
        , to_date DATE
      )
    
      RETURNS REAL
    
      AS
        $$
          WITH
              aux_1 AS (  -- Auxiliary table
                SELECT
                    AGE(to_date, from_date) AS duration
              )
    
            , aux_2 AS (  -- Auxiliary table
                SELECT
                    (from_date + DATE_TRUNC('MONTH', duration))::DATE AS to_date_floor
                  , (from_date + DATE_TRUNC('MONTH', duration + INTERVAL '1 MONTH'))::DATE AS to_date_ceil
                FROM
                  aux_1
              )
    
          SELECT
            CASE WHEN
              to_date >= from_date
            THEN
              (12 * EXTRACT(YEAR FROM duration) + EXTRACT(MONTH FROM duration) + (to_date - to_date_floor)::REAL / (to_date_ceil - to_date_floor)::REAL)::REAL
            ELSE
              NULL
            END
    
          FROM
            aux_1, aux_2
        $$
    
      LANGUAGE SQL
      IMMUTABLE
      RETURNS NULL ON NULL INPUT;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多