Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More
The Born
mixin¶
This document explains the lino.mixins.human.Born
model mixin which
defines a database field Born.birth_date
and a virtual field
Born.age
.
Side note: Code snippets (lines starting with >>>
) in this document get
tested as part of our development workflow. The following
initialization snippet tells you which demo project is being used in
this document.
>>> import lino
>>> lino.startup('lino_book.projects.avanti1.settings')
>>> from lino.api.doctest import *
>>> from django.db.models import Q
>>> from lino_avanti.lib.contacts.models import Person
>>> from lino.modlib.system.choicelists import Genders
>>> from django.utils import translation
This tutorial uses the same demo database as The Human mixin (see there for more explanations).
The age of a human¶
For the following examples, we will set the_demo_date
in order to have reproducible test cases.
At the end of this page we will need to restore the demo date to its original
value, which is None:
>>> the_demo_date = settings.SITE.the_demo_date
>>> print(the_demo_date)
2017-02-15
We define a utility function for our tests:
>>> def test(birth_date, today):
... settings.SITE.the_demo_date = i2d(today)
... p = Person(birth_date=birth_date, name="Joe")
... p.full_clean()
... print(p.age)
... settings.SITE.the_demo_date = None
Here we go.
A person born on April 5, 2002 was 16 years old on June 11, 2018:
>>> test("2002-04-05", 20180611)
16 years
When you get 16 years old tomorrow, then today you are still 15:
>>> test("2002-04-05", 20180404)
15 years
You start being 16 on your birthday.
>>> test("2002-04-05", 20180405)
16 years
For children younger than 5 years Lino adds the number of months:
>>> test("2018-03-01", 20180611)
0 years 3 months
Lino respects the singular forms:
>>> test("2017-05-01", 20180611)
1 year 1 month
Incomplete birth dates¶
The birth date is an instance of lino.utils.IncompleteDate
. Yes, there
are people who don’t know their exact birth date.
>>> test("2002-05-00", 20180611)
±16 years
>>> test("2002-00-00", 20180611)
±15 years
If you say only your birth day but not the year, then we don’t know your age:
>>> test("0000-06-01", 20180611)
unknown
Other languages¶
The age is translated text:
>>> with translation.override('de'):
... test("2018-03-01", 20180611)
0 Jahre 3 Monate
>>> with translation.override('de'):
... test("2017-05-01", 20180611)
1 Jahr 1 Monat
>>> with translation.override('fr'):
... test("2017-05-01", 20180611)
1 an 1 mois
>>> with translation.override('fr'):
... test("0000-05-01", 20180611)
inconnu
The leap year bug¶
In April 2019 Steve reported #2946: Lino was saying 35 years as age of a person whose birth date was 10.04.1984 when today is 04.04.2019. Which is wrong. The person will get 35 only in 6 days. So today she is 34:
>>> test("1984-04-10", 20190404)
34 years
It is now correct since the bug is fixed. We added some more test cases
>>> test("2002-04-05", 20180403)
15 years
>>> test("2002-04-05", 20180402)
15 years
>>> test("2002-04-05", 20180401)
15 years
>>> test("2002-04-05", 20180331)
15 years
The explanation was that each leap year caused one day of difference. In our case the leap years were 2004, 2008 and 2012 and 2016, so Lino starts saying 16 4 days before your birthday:
Restore the_demo_date for subsequent tests:
>>> settings.SITE.the_demo_date = the_demo_date