来自python的诞生日期

tka*_*lve 142 python datetime date

我怎样才能从今天的日期和一个人的出生日期中找到蟒蛇的年龄?birthdate来自Django模型中的DateField.

Dan*_*air 255

考虑到int(True)为1且int(False)为0,可以做得更简单:

from datetime import date

def calculate_age(born):
    today = date.today()
    return today.year - born.year - ((today.month, today.day) < (born.month, born.day))
Run Code Online (Sandbox Code Playgroud)

  • 这可能取决于你对"年龄"的定义.出于所有实际目的,生日通常作为日期给出,而不是时区感知日期时间(即,"出生"缺少细节).大多数人不是在午夜出生(所以通常过早地观察:-)),当在不同的时区,我会假设大多数人在当地时间观察他们的生日(这就是我做的,我活在10-12h前面我的出生地时间).如果"天生"是一个时区感知的日期时间,你可以使用pytz的算术和normalize() - 可能对占星术软件感兴趣? (8认同)
  • nitpick:date.today()返回本地时区中的日期,该日期可能与出生地不同。您可能需要[明确使用时区](http://stackoverflow.com/a/32658742/4279) (3认同)
  • 我完全同意人类时代的观点,但您的公式可能会在更广泛的范围内使用。尽管由于家族传统和程序员的缘故,我个人甚至从未提前一个小时庆祝生日,但无论我在哪里,计算时间都是微不足道的。 (2认同)

mpe*_*pen 68

from datetime import date

def calculate_age(born):
    today = date.today()
    try: 
        birthday = born.replace(year=today.year)
    except ValueError: # raised when birth date is February 29 and the current year is not a leap year
        birthday = born.replace(year=today.year, month=born.month+1, day=1)
    if birthday > today:
        return today.year - born.year - 1
    else:
        return today.year - born.year
Run Code Online (Sandbox Code Playgroud)

更新:使用Danny的解决方案,它会更好

  • 原则上,你的`except`块应该只捕获可能引发的一个特定异常. (2认同)

The*_*One 16

from datetime import date

days_in_year = 365.2425    
age = int((date.today() - birth_date).days / days_in_year)
Run Code Online (Sandbox Code Playgroud)

在Python 3中,您可以执行除法datetime.timedelta:

from datetime import date, timedelta

age = (date.today() - birth_date) // timedelta(days=365.2425)
Run Code Online (Sandbox Code Playgroud)

  • @Dan:如果你的生活不到130年,朱利安(`365.25`)和阳历年(`365.2425`)之间的差异不到一天. (3认同)
  • 每四年都是闰年,除了evey百年不是闰年,除了每四百年是闰年.试试days_in_year = 365.2425 (2认同)
  • 这不适用于*某些*日期:`(日期(2017年,3年,1年) - 日期(2004年,3年级,1年))/ timedelta(天数= 365.2425)`应返回"13",但它返回"12" `.未受欢迎,结果是`12.999582469181433`. (2认同)

Aru*_*tri 11

正如@ [Tomasz Zielinski]和@Williams所建议的那样,python-dateutil只能做5行.

from dateutil.relativedelta import *
from datetime import date
today = date.today()
dob = date(1982, 7, 5)
age = relativedelta(today, dob)

>>relativedelta(years=+33, months=+11, days=+16)`
Run Code Online (Sandbox Code Playgroud)


use*_*050 8

最简单的方法是使用 python-dateutil

import datetime

import dateutil

def birthday(date):
    # Get the current date
    now = datetime.datetime.utcnow()
    now = now.date()

    # Get the difference between the current date and the birthday
    age = dateutil.relativedelta.relativedelta(now, date)
    age = age.years

    return age
Run Code Online (Sandbox Code Playgroud)

  • 当生日是在2月29日,而今天的日期是2月28日(这将好像今天是2月29日),这不能正常工作. (6认同)

gze*_*one 6

from datetime import date

def age(birth_date):
    today = date.today()
    y = today.year - birth_date.year
    if today.month < birth_date.month or today.month == birth_date.month and today.day < birth_date.day:
        y -= 1
    return y
Run Code Online (Sandbox Code Playgroud)


Ale*_*dev 5

不幸的是,你不能只使用timedelata作为它使用的最大单位是日和闰年将使你的计算无效.因此,如果去年未满,我们可以找到年数,然后调整一年:

from datetime import date
birth_date = date(1980, 5, 26)
years = date.today().year - birth_date.year
if (datetime.now() - birth_date.replace(year=datetime.now().year)).days >= 0:
    age = years
else:
    age = years - 1
Run Code Online (Sandbox Code Playgroud)

UPD:

当2月29日发挥作用时,这个解决方案确实会导致异常.这是正确的检查:

from datetime import date
birth_date = date(1980, 5, 26)
today = date.today()
years = today.year - birth_date.year
if all((x >= y) for x,y in zip(today.timetuple(), birth_date.timetuple()):
   age = years
else:
   age = years - 1
Run Code Online (Sandbox Code Playgroud)

UPD2:

多次调用now()性能命中是荒谬的,除了非常特殊的情况外,它并不重要.使用变量的真正原因是数据不完整的风险.

  • Strike 1:您使用的是datetime.datetime而不是datetime.date.罢工2:你的代码很丑陋,效率低下.调用datetime.now()**三次**次?罢工3:出生日期2004年2月29日和今天的日期2010年2月28日应该返回6岁,而不是尖叫"ValueError:一天超出了一个月的范围".你出去了! (3认同)

Ano*_*oyz 5

如果您想使用 django 模板在页面中打印此内容,那么以下内容可能就足够了:

{{ birth_date|timesince }}
Run Code Online (Sandbox Code Playgroud)

  • 不要使用 Django 的 `|timesince` 来计算几年内的时间增量,因为它不考虑闰年,从而产生不准确的结果。有关详细信息,请参阅 Django 票证 #19210。 (6认同)