How to calculate next birthday given a date of birth?

萝らか妹 提交于 2021-02-07 12:53:47

问题


Given this schema in a Postgres database:

CREATE TABLE person (
    id serial PRIMARY KEY,
    name text,
    birth_date date,
);

How would I query the table to get the date of each person's next birthday after today?

For example if Bob's birth_date is 2000-06-01 then his next birthday would be 2016-06-01.

Note: I'm not looking for the birth_date + a pre-defined interval but rather the next anniversary of a person's birth.

I've written the equivalent in Python:

def next_birthday(self):
    today = datetime.date.today()
    next_birthday = self.birth_date.replace(year=today.year)
    if next_birthday < today:
        next_birthday = next_birthday.replace(year=today.year + 1)
    return next_birthday

However I'd like to see if Postgres can do this in a more performant way.


回答1:


select birth_date,
       cast(birth_date + ((extract(year from age(birth_date)) + 1) * interval '1' year) as date) as next_birthday
from person
where name = 'Bob'

The expression (extract(year from age(birth_date)) + 1) * interval '1' year calculates the age at the next birthday in (complete) years. When adding that to the date of birth, this gives the next birthday.

The cast is necessary to get a real date back, because date + interval returns a timestamp (including a time).

If you remove the where condition, you'll get all "next" birthdays.

You can also get a list of the upcoming birthdays in e.g. the next 30 days using something like this:

select next_birthday,
       next_birthday - current_date as days_until_next
from (
  select birth_date,
         cast(birth_date + ((extract(year from age(birth_date)) + 1) * interval '1' year) as date) as next_birthday
  from person
) as upcoming
where upcoming.next_birthday <= current_date + 30
order by next_birthday;



回答2:


SELECT
    birth_date
    +
    cast(
        date_part('year', current_date)
        -
        date_part('year', birth_date)
        +
        CASE
            WHEN
                date_part('month', birth_date) <
                        date_part('month', current_date)
                OR (
                    date_part('month', birth_date) =
                            date_part('month', current_date)
                    AND
                    date_part('day', birth_date) <
                            date_part('day', current_date)
                )
            THEN 1
            ELSE 0
        END || ' year' as interval)
FROM person;



回答3:


SELECT date birth_date + interval '1 year' as next_birthday from person;



来源:https://stackoverflow.com/questions/37081182/how-to-calculate-next-birthday-given-a-date-of-birth

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!