From 575fc75461a854f1fe468cb91a0332d0ffedc18d Mon Sep 17 00:00:00 2001 From: Arthur de Jong Date: Sun, 5 Feb 2012 20:51:19 +0000 Subject: add a RČ (Rodné číslo, the Czech birth numbers) module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://arthurdejong.org/svn/python-stdnum/python-stdnum@101 9dea7c4f-944c-4273-ac1a-574ede026edc --- stdnum/cz/__init__.py | 0 stdnum/cz/rc.py | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 stdnum/cz/__init__.py create mode 100644 stdnum/cz/rc.py (limited to 'stdnum/cz') diff --git a/stdnum/cz/__init__.py b/stdnum/cz/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/stdnum/cz/rc.py b/stdnum/cz/rc.py new file mode 100644 index 0000000..eccc8ca --- /dev/null +++ b/stdnum/cz/rc.py @@ -0,0 +1,97 @@ +# rc.py - functions for handling Czech birth numbers +# coding: utf-8 +# +# Copyright (C) 2012 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +"""Module for handling Czech birth numbers (RČ, Rodné číslo), the Czech +national identifier. + +>>> compact('710319/2745') +'7103192745' +>>> is_valid('7103192745') +True +>>> is_valid('991231123') +True +>>> is_valid('7103192746') # invalid check digit +False +>>> is_valid('1103492745') # invalid date +False +>>> is_valid('590312/123') # 9 digit number in 1959 +False +>>> format('7103192745') +'710319/2745' +""" + +import datetime + +from stdnum.util import clean + + +def compact(number): + """Convert the number to the minimal representation. This strips the + number of any valid separators and removes surrounding whitespace.""" + return clean(number, ' /').upper().strip() + + +def _get_birth_date(number): + """Split the date parts from the number and return the birth date.""" + year = 1900 + int(number[0:2]) + # females have 50 added to the month value, 20 is added when the serial + # overflows (since 2004) + month = int(number[2:4]) % 50 % 20 + day = int(number[4:6]) + # 9 digit numbers were used until January 1st 1954 + if len(number) == 9: + if year >= 1980: + year -= 100 + if year > 1953: + raise ValueError('No 9 digit birth numbers after 1953.') + elif year < 1954: + year += 100 + return datetime.date(year, month, day) + + +def is_valid(number): + """Checks to see if the number provided is a valid birth number. This + checks the length, formatting, embedded date and check digit.""" + try: + number = compact(number) + except: + return False + if not number.isdigit() or len(number) not in (9, 10): + return False + # check if birth date is valid + try: + birth_date = _get_birth_date(number) + # TODO: check that the birth date is not in the future + except ValueError, e: + return False + # check the check digit + if len(number) == 10: + check = int(number[:-1]) % 11 + # before 1985 the checksum could be 0 or 10 + if birth_date < datetime.date(1985, 1, 1): + check = check % 10 + return number[-1] == str(check) + return True + + +def format(number): + """Reformat the passed number to the standard format.""" + number = compact(number) + return number[:6] + '/' + number[6:] -- cgit v1.2.3