从Oracle中的日期差异计算年份

Posted

技术标签:

【中文标题】从Oracle中的日期差异计算年份【英文标题】:Calculate year from date difference in Oracle 【发布时间】:2013-09-30 17:42:11 【问题描述】:

我想计算两个日期之间的年数。

例如:- Select to_date('30-OCT-2013') - TO_date('30-SEP-2014') FROM DUAL;

这将导致 335 天。我想以年为单位展示这一点,即.97 年。

【问题讨论】:

【参考方案1】:

只需这样做(除以 365.242199):

Select (to_date('30-SEPT-2014') - TO_date('30-OCT-2013'))/365.242199 FROM DUAL;

1 年 = 365.242199 天

使用MONTHS_BETWEEN:-

尝试这样的事情
select floor(months_between(date '2014-10-10', date '2013-10-10') /12) from dual;

或者你也可以试试这个:-

SELECT EXTRACT(YEAR FROM date1) - EXTRACT(YEAR FROM date2) FROM DUAL;

附带说明:-

335/365.242199 = 0.917199603 而不是 0.97

【讨论】:

从 DUAL 中选择 (to_date('30-OCT-2013') - TO_date('30-SEP-2014'))/12;不工作......它给出 -25.333333333333 作为答案 @sonakshisinha:- 还要更改日期的位置以去掉减号。!! :) 我想避免将日期除以 365 天......因为闰年是 366 年,否则是 365 ORA-01841:(完整)年份必须介于 -4713 和 +9999 之间,并且不能为 0:选择 (to_date('30-SEPT-2014') - TO_date('30-OCT- 2013'))/365.242199 来自双重 @sonakshisinha:- 最可能的错误原因是您尝试使用指定的日期格式输入日期值,但您输入了一个非数字字符,而该字符应该是数字字符。跨度> 【参考方案2】:

我不知道你是怎么计算出 0.97 年的。这是我得到的:

SQL> SELECT  ( TO_date('30-SEP-2014') - to_date('30-OCT-2013')) /
                (ADD_MONTHS(DATE '2013-10-30',12) - DATE '2013-10-30') "Year Fraction" 
       FROM DUAL;

Year Fraction
-------------
0.91780821917

您必须选择一个日期来计算年份。这是一种方法。我选择将一年设为 2013 年 10 月 30 日和 2014 年 10 月 30 日之间的天数。您也可以在 2013 年 9 月 30 日到 2014 年 9 月 30 日之间度过一年。

顺便说一句,如果您只对小数点后 2 位感兴趣,那么 365 与 366 差不多。

更新:在计算分母时使用了 ADD_MONTHS。这样您就可以使用同一日期来计算一年中的天数。

【讨论】:

OP 在我的 cmets 中提到她希望避免将日期除以 365 天 :( 基本上我想用这个作为我的条件之一。我想在两个日期之间计算 @Rahul,我宁愿 3/4 的时候是对的,也不愿一直错 :-) @DCookie:- 我没说你错了。我只是试图提供我的 cmets 中的 OP 要求的详细信息。我们俩都在同一页面上。 ;) @Rahul,一点也不冒犯。我觉得这很有趣。【参考方案3】:

其他答案中提出的方法都没有给出完全相同的答案,请看:

with dates as ( select to_date('2013-10-01', 'YYYY-MM-DD') as date1, to_date('2014-09-01', 'YYYY-MM-DD') as date2 from dual)

select months_between(date2, date1)/12 as years_between, 'months_between(date1, date2)' as method from dates
union
select (date2 - date1)/365.242199, '(date2 - date1) / 365.242199' from dates
union
select extract(year from date2) - extract(year from date1), 'extract(year) from date2 - extract(year from date1)' from dates
union
select (date2 - date1) / (ADD_MONTHS(date1 ,12) - date1), '(nb days between date1 and date2) / (nb days in 1 year starting at date1)' from dates
;

给予

YEARS_BETWEEN                               METHOD

0.9166666666666666666666666666666666666667  months_between(date1, date2)
0.9171996032145234127231831719422979380321  (date2 - date1) / 365.242199
0.9178082191780821917808219178082191780822  nb days date2-date1 / (nb days in 1 year starting at date1)
1                                           extract(year) from date2 - extract(year from date1)

为什么?因为他们都在回答略有不同的问题。

MONTHS_BETWEEN 给出两个日期之间的整月数,并将小数部分计算为天数除以 31 的余数。 除以 365.242199 假设您希望将第一个日期的 00:00 和第二个日期的 00:00 之间的太阳年数设为 9 位有效数字。 第三种方法假设您要计算两个日期之间的日历天数,相对于从第一个日期开始的特定年份的日历天数(因此相同的日历天数会给您不同的年数,取决于 date1 和下一年的同一日期之间是否有闰日)。 extract(year) 方法假定您想知道第一个日期的日历年和第二个日期的日历年之间的整数差

在不知道我们谈论的是哪一年的情况下,不可能完美地回答这个问题。我们是指一个太阳年,还是一个日历年,如果我们指的是一个日历年,我们是要按月计算(好像所有月份的长度相同,但它们不是)还是按实际数量来计算?这些日期和特定年份之间的天数?

确实,如果我们谈论的是日历年,那么根本不可能以一致的方式计算小数年数,因为“日历年”的概念并不对应于固定的天数。

好消息是(除了第四种方法)所有方法都对前 2 个有效数字给出了相同的答案,正如 DCookie 所说。因此,当您说“年份”时,您可以不必担心您的意思,而是开始考虑其他问题,例如性能、可移植性、可读性……这些方法在这些方法之间也有很大不同。

但我确实认为,每当一个非程序员要求“两个日期之间的小数年数”之类的东西时,他们应该受到惩罚,详细解释计算它的不同方法,以及为什么和它们有什么不同,直到他们同意最好用周数表示(这至少有包含固定天数的好处)。

【讨论】:

以上是关于从Oracle中的日期差异计算年份的主要内容,如果未能解决你的问题,请参考以下文章

使用 C# 的年份日期差异 [重复]

计算 Oracle SQL 中 2 个日期/时间之间的差异

SQL Server 2012 中的年份计算

如何在java中计算两个日期之间的年龄或差异

oracle根据出生日期算年龄

oracle根据出生日期算年龄