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

https://code.google.com/p/mango-py/ · Python · 84 lines · 48 code · 21 blank · 15 comment · 19 complexity · 9e10fa000327128d783e8d0aac1626cc MD5 · raw file

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