#### /django/contrib/localflavor/se/utils.py

Python | 84 lines | 81 code | 1 blank | 2 comment | 0 complexity | 9e10fa000327128d783e8d0aac1626cc MD5 | raw file
``` 1import re
2import datetime
3
4def id_number_checksum(gd):
5    """
6    Calculates a Swedish ID number checksum, using the
7    "Luhn"-algoritm
8    """
9    n = s = 0
10    for c in (gd['year'] + gd['month'] + gd['day'] + gd['serial']):
11        tmp = ((n % 2) and 1 or 2) * int(c)
12
13        if tmp > 9:
14            tmp = sum([int(i) for i in str(tmp)])
15
16        s += tmp
17        n += 1
18
19    if (s % 10) == 0:
20        return 0
21
22    return (((s / 10) + 1) * 10) - s
23
24def validate_id_birthday(gd, fix_coordination_number_day=True):
25    """
26    Validates the birth_day and returns the datetime.date object for
27    the birth_day.
28
29    If the date is an invalid birth day, a ValueError will be raised.
30    """
31
32    today = datetime.date.today()
33
34    day = int(gd['day'])
35    if fix_coordination_number_day and day > 60:
36        day -= 60
37
38    if gd['century'] is None:
39
40        # The century was not specified, and need to be calculated from todays date
41        current_year = today.year
42        year = int(today.strftime('%Y')) - int(today.strftime('%y')) + int(gd['year'])
43
44        if ('%s%s%02d' % (gd['year'], gd['month'], day)) > today.strftime('%y%m%d'):
45            year -= 100
46
47        # If the person is older than 100 years
48        if gd['sign'] == '+':
49            year -= 100
50    else:
51        year = int(gd['century'] + gd['year'])
52
53        # Make sure the year is valid
54        # There are no swedish personal identity numbers where year < 1800
55        if year < 1800:
56            raise ValueError
57
58    # ValueError will be raise for invalid dates
59    birth_day = datetime.date(year, int(gd['month']), day)
60
61    # birth_day must not be in the future
62    if birth_day > today:
63        raise ValueError
64
65    return birth_day
66
67def format_personal_id_number(birth_day, gd):
68    # birth_day.strftime cannot be used, since it does not support dates < 1900
69    return unicode(str(birth_day.year) + gd['month'] + gd['day'] + gd['serial'] + gd['checksum'])
70
71def format_organisation_number(gd):
72    if gd['century'] is None:
73        century = ''
74    else:
75        century = gd['century']
76
77    return unicode(century + gd['year'] + gd['month'] + gd['day'] + gd['serial'] + gd['checksum'])
78
79def valid_organisation(gd):
80    return gd['century'] in (None, 16) and \
81        int(gd['month']) >= 20 and \
82        gd['sign'] in (None, '-') and \
83        gd['year'][0] in ('2', '5', '7', '8', '9') # group identifier
84
```