如何获得一个月中的下一个日期

时间:2018-10-24 23:23:59

标签: postgresql date

谢谢您的阅读,这是情况

我有一个current_date和一个月中的某天,因此我要知道某个月的日期不是30和31,因此我需要知道该月的这一天的下一个日期。

示例:

  • current_date ='2018-09-24'
  • day_of_week = 31

预期结果:“ 2018-12-31”

目前我有这个:

create or replace function next_diff(vals int[], current_val int) returns int as 
$$
declare v int;
declare o int := vals[1];
begin
    foreach v in array vals loop
    if current_val >= o and current_val < v then
       return v - current_val;
    end if;
    o := v;
    end loop;
    return vals[1] - current_val;
end;
$$ language plpgsql;

这:

create or replace function next_day_of_month(days_of_month int[], curr_date date) returns date as 
$$
declare cur_dom int := extract(day from curr_date);
declare next_diff int := next_diff(days_of_month, cur_dom);
begin
    if next_diff < 0 then
    curr_date := curr_date + '1 months'::interval;
    end if;
    curr_date := curr_date + (next_diff || 'days')::interval;
    return curr_date;
end;
$$ language plpgsql;

但为此调用:

select next_day_of_month(array[31], '2018-09-24');

我正在:

“ 2018-10-01”

更多示例

如果我有这个值

  • current_date ='2018-02-01'
  • day_of_week = 31

我需要下个月的31号,但是我不能得到“ 2018-02-31”,因为2月没有31号,那么我应该得到“ 2018-02-31”,因为3月有31号。

结论

如果月份没有指定的日期,则必须忽略该月份并跳转到下一个日期。

感谢所有人

最终方法

使用卡洛斯·戈麦斯(Carlos Gomez)的答案,我创建了这个PostgreSQL函数并完美地工作:

create or replace function next_day_date(curr_date date, day_of_month int) returns date as 
$$
declare next_day date;
begin
    SELECT next_day_date into next_day FROM (
      SELECT make_date_nullable(EXTRACT(year from n.month)::int, EXTRACT(month from n.month)::int, day_of_month) AS next_day_date
      FROM (
        SELECT generate_series(curr_date, curr_date + '3 months'::interval, '1 month'::interval) as month
          ) n
      ) results
      WHERE results.next_day_date IS NOT NULL and results.next_day_date > curr_date  LIMIT 1;
      return next_day;
end;
$$ language plpgsql;

只需在where子句and results.next_day_date > curr_date中添加其他过滤器,以防止在指定日期获得相同或先前的值

感谢大家的帮助

Thenks Carlos你是最好的

Gracias carlos eres el mejor:)

1 个答案:

答案 0 :(得分:0)

您的示例并不完全匹配,但我想我知道您要解决的问题(您的第一个示例结果应为“ 2018-10-31”,因为十月份有31天,而第二个示例结果应为“ 2018-03-31')。似乎给定一个日期和一个月中的某天,您想查找具有该月中的下个月的下个月。为此,我将执行以下操作:

此函数仅包装make_date使其返回null,因为如果给定的日期超出范围(例如2月30日),它将引发异常。

CREATE OR REPLACE FUNCTION make_date_nullable(year int, month int, day int)
RETURNS date as $$
BEGIN
  RETURN make_date(year, month, day);
EXCEPTION WHEN others THEN RETURN null;
END;
$$ language plpgsql;

此SELECT首先从当前月份开始生成接下来的三个月,然后使用您提供的day_of_month来确定日期,最后得到第一个不为null的日期(根据postgresql存在。) >

SELECT next_day_date FROM (
  SELECT make_date_nullable(EXTRACT(year from n.month)::int, EXTRACT(month from n.month)::int, day_of_month) AS next_day_date
  FROM (
        SELECT generate_series(current_date, current_date + '3 months'::interval, '1 month'::interval) as month
      ) n
  ) results
  WHERE results.next_day_date IS NOT NULL LIMIT 1;

希望这会有所帮助!