Skip to content

Commit

Permalink
Add birth date check to PESEL validation
Browse files Browse the repository at this point in the history
  • Loading branch information
emesik authored and benkonrath committed Nov 5, 2016
1 parent 140f123 commit fb5976c
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
26 changes: 26 additions & 0 deletions localflavor/pl/forms.py
Expand Up @@ -4,6 +4,7 @@

from __future__ import unicode_literals

import datetime
import re

from django.core.validators import EMPTY_VALUES
Expand Down Expand Up @@ -38,12 +39,16 @@ class PLPESELField(RegexField):
Checks the following rules:
* the length consist of 11 digits
* has a valid checksum
* contains a valid birth date
The algorithm is documented at http://en.wikipedia.org/wiki/PESEL.
.. versionchanged:: 1.4
"""
default_error_messages = {
'invalid': _('National Identification Number consists of 11 digits.'),
'checksum': _('Wrong checksum for the National Identification Number.'),
'birthdate': _('The National Identification Number contains an invalid birth date.'),
}

def __init__(self, max_length=None, min_length=None, *args, **kwargs):
Expand All @@ -56,6 +61,8 @@ def clean(self, value):
return ''
if not self.has_valid_checksum(value):
raise ValidationError(self.error_messages['checksum'])
if not self.has_valid_birth_date(value):
raise ValidationError(self.error_messages['birthdate'])
return '%s' % value

def has_valid_checksum(self, number):
Expand All @@ -68,6 +75,25 @@ def has_valid_checksum(self, number):
result += int(number[i]) * multiple_table[i]
return result % 10 == 0

def has_valid_birth_date(self, number):
"""
Checks whether the birth date encoded in PESEL is valid.
"""
y = int(number[:2])
m = int(number[2:4])
d = int(number[4:6])
md2century = {80: 1800, 0: 1900, 20: 2000, 40: 2100, 60: 2200}
for md, cent in md2century.items():
if 1 <= m - md <= 12:
y += cent
m -= md
break
try:
self.birth_date = datetime.date(y, m, d)
return True
except ValueError:
return False


class PLNationalIDCardNumberField(RegexField):
"""
Expand Down
2 changes: 2 additions & 0 deletions tests/test_pl.py
Expand Up @@ -439,13 +439,15 @@ def test_PLNIPField(self):
def test_PLPESELField(self):
error_checksum = ['Wrong checksum for the National Identification Number.']
error_format = ['National Identification Number consists of 11 digits.']
error_birthdate = ['The National Identification Number contains an invalid birth date.']
valid = {
'80071610614': '80071610614',
}
invalid = {
'80071610610': error_checksum,
'80': error_format,
'800716106AA': error_format,
'98765432121': error_birthdate,
}
self.assertFieldOutput(PLPESELField, valid, invalid)

Expand Down

0 comments on commit fb5976c

Please sign in to comment.