web/lib/django/contrib/localflavor/se/utils.py
changeset 29 cc9b7e14412b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/lib/django/contrib/localflavor/se/utils.py	Tue May 25 02:43:45 2010 +0200
@@ -0,0 +1,84 @@
+import re
+import datetime
+
+def id_number_checksum(gd):
+    """
+    Calculates a Swedish ID number checksum, using the
+    "Luhn"-algoritm
+    """
+    n = s = 0
+    for c in (gd['year'] + gd['month'] + gd['day'] + gd['serial']):
+        tmp = ((n % 2) and 1 or 2) * int(c)
+
+        if tmp > 9:
+            tmp = sum([int(i) for i in str(tmp)])
+ 
+        s += tmp
+        n += 1
+
+    if (s % 10) == 0:
+        return 0
+
+    return (((s / 10) + 1) * 10) - s
+
+def validate_id_birthday(gd, fix_coordination_number_day=True):
+    """
+    Validates the birth_day and returns the datetime.date object for
+    the birth_day.
+
+    If the date is an invalid birth day, a ValueError will be raised.
+    """
+    
+    today = datetime.date.today()
+    
+    day = int(gd['day'])
+    if fix_coordination_number_day and day > 60:
+        day -= 60
+
+    if gd['century'] is None:
+
+        # The century was not specified, and need to be calculated from todays date
+        current_year = today.year
+        year = int(today.strftime('%Y')) - int(today.strftime('%y')) + int(gd['year'])
+   
+        if ('%s%s%02d' % (gd['year'], gd['month'], day)) > today.strftime('%y%m%d'):
+            year -= 100
+
+        # If the person is older than 100 years
+        if gd['sign'] == '+':
+            year -= 100
+    else:
+        year = int(gd['century'] + gd['year'])
+        
+        # Make sure the year is valid
+        # There are no swedish personal identity numbers where year < 1800
+        if year < 1800:
+            raise ValueError
+
+    # ValueError will be raise for invalid dates
+    birth_day = datetime.date(year, int(gd['month']), day)
+    
+    # birth_day must not be in the future
+    if birth_day > today:
+        raise ValueError
+    
+    return birth_day
+
+def format_personal_id_number(birth_day, gd):
+    # birth_day.strftime cannot be used, since it does not support dates < 1900
+    return unicode(str(birth_day.year) + gd['month'] + gd['day'] + gd['serial'] + gd['checksum'])
+
+def format_organisation_number(gd):
+    if gd['century'] is None:
+        century = ''
+    else:
+        century = gd['century']
+
+    return unicode(century + gd['year'] + gd['month'] + gd['day'] + gd['serial'] + gd['checksum'])
+
+def valid_organisation(gd):
+    return gd['century'] in (None, 16) and \
+        int(gd['month']) >= 20 and \
+        gd['sign'] in (None, '-') and \
+        gd['year'][0] in ('2', '5', '7', '8', '9') # group identifier
+