【问题标题】:plsql - oracle add_months adding additional dayplsql - oracle add_months 添加额外的一天
【发布时间】:2017-03-16 16:04:58
【问题描述】:

甲骨文: 12c

说明: 尝试使用 add_months 将 99 年添加到日期,但它会在返回日期值上增加一天。我应该如何正确地将年份添加到日期?

declare 
  toRetDate DATE;
  inputDate DATE;
  numYears number;
begin

  numYears := 99;
  inputDate := TO_DATE('28-FEB-85', 'DD-Mon-YY' );
  toRetDate := add_months(inputDate, numYears*12);
  DBMS_OUTPUT.put_line(toRetDate);
end;

输出:29-FEB-84

【问题讨论】:

  • 正如我在回答中所解释的,ADD_MONTHS 不会随机“添加一天”到结果中。有了这个解释:你真的需要结果是 84 年 2 月 28 日吗?如果是这样,为什么?为什么 2 月 29 日不行?
  • 我希望明确添加年份但保留同一天。根据我的问题,它规定仅在日期中添加年份。当然,这种情况的例外是 2 月 29 日。

标签: oracle plsql


【解决方案1】:

ADD_MONTHS 不会在结果中添加一天。相反,它有一个非常通用的特性:如果您将 MONTHS 添加到某个日期,并且该日期是该特定月/年的月末,则 ADD_MONTHS 的结果是生成月份的最后一天。

因此,例如,如果您在 1 月 31 日加上一个月,您总是会得到 2 月 28 日(或闰年的 2 月 29 日)。如果在 6 月 30 日加上一个月,则得到 7 月 31 日。

如果您在 2 月 28 日加上一个月,则得到 3 月 31 日,除非它是闰年;在闰年中,2 月 28 日不是该月的最后一天,因此如果您在其中添加一个月,则会得到 3 月 28 日。

在所有情况下,如果结果的天数大于生成月份的天数,则结果只是该月的最后一天。

编辑:在此答案下方的评论中,OP 询问是否有办法保持一个月中的同一天,除了 2 月 29 日(应该变成 2 月)。 28 在非闰年)。

答案是肯定的。正如@Xing 在另一个答案中显示的那样,添加interval '99' year 将保留日期,但当输入日期为2 月29 日且结果年份不是闰年时,可能会导致麻烦。这可以通过初步检查来解决。可以使用 IF 语句或 CASE 表达式来完成。我更喜欢后者,因为它在 PL/SQL 和 SQL 中的工作方式相同;普通 SQL 中没有 IF。

toretdate := case when to_char(inputdate, 'mm-dd') = '02-29'
                  then (inputdate + 1) + interval '99' year - 1
                  else inputdate + interval '99' year end

诀窍是,当inputdate 是 2 月 29 日时,将其向前推一天使其成为 3 月 1 日,然后加上 99 年(仍然是 3 月 1 日),然后减去一天使其成为 2 月 29 日(如果这是闰年)或 2 月 28 日(否则)。

【讨论】:

  • 有没有更好的方法来增加时间让它坚持到同一天?在我的情况下是28号?我已阅读有关间隔功能如何导致无效日期的信息。但是我在想,因为我只想添加年份,所以为了保持同一天但只添加年份就足够了。除非是2月29日。唯一的例外。
【解决方案2】:

你可以这样使用:

declare 
  toRetDate DATE;
  inputDate DATE;
  numYears number;
begin

  numYears := 99;
  inputDate := TO_DATE('28-FEB-1985', 'DD-Mon-YYYY' );
  toRetDate := inputDate + INTERVAL '99' YEAR; --add_months(inputDate, numYears*12);
  DBMS_OUTPUT.put_line(to_date(toRetDate,'dd-mon-yyyy'));
end;

虽然值得注意的是,带有间隔的算术是有限的(如果没有破坏的话),因为它只是“增加”日期值的月/年值。这可能会导致日期无效(例如从一月到二月)。

编辑: 一般Add_months 通常会在其应用日期添加30/31(取决于月份)。每个月的情况略有不同。如果 add_monthsFEBURARY 的月份完成,它会增加 (28/29) 天,具体取决于 leap year 与否。 如果您的要求是简单地添加99 years 而不检查结果日期是否为valiad,那么您可以使用INTERVAL,但如果您真的想检查结果日期是否应该得到很好的评估和正确的日期然后你必须你的ADD_MONTHS。首先使用INTERVAL 然后检查结果日期(使用任何逻辑)是否是有效日期不会使任何sense。 Oracle 已经为此类场景提供了解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-09
    • 2022-08-23
    • 2011-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多