/django/contrib/localflavor/se/utils.py
Python | 84 lines | 81 code | 1 blank | 2 comment | 0 complexity | 9e10fa000327128d783e8d0aac1626cc MD5 | raw file
Possible License(s): BSD-3-Clause
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