Code

Ticket #9289: django_localflavor_se.diff

File django_localflavor_se.diff, 51.4 KB (added by peritus, 6 years ago)

Swedish localflavor patch against current trunk

Line 
1diff --git a/AUTHORS b/AUTHORS
2index 7bbec38..558f0ff 100644
3--- a/AUTHORS
4+++ b/AUTHORS
5@@ -297,6 +297,7 @@ answer newbie questions, and generally made Django that much better:
6     Carlos Eduardo de Paula <carlosedp@gmail.com>
7     pavithran s <pavithran.s@gmail.com>
8     Barry Pederson <bp@barryp.org>
9+    Andreas Pelme <andreas@pelme.se>
10     permonik@mesias.brnonet.cz
11     peter@mymart.com
12     pgross@thoughtworks.com
13diff --git a/django/conf/locale/sv/LC_MESSAGES/django.mo b/django/conf/locale/sv/LC_MESSAGES/django.mo
14index f2ae006..ea2dc58 100644
15Binary files a/django/conf/locale/sv/LC_MESSAGES/django.mo and b/django/conf/locale/sv/LC_MESSAGES/django.mo differ
16diff --git a/django/conf/locale/sv/LC_MESSAGES/django.po b/django/conf/locale/sv/LC_MESSAGES/django.po
17index d279647..5a75119 100644
18--- a/django/conf/locale/sv/LC_MESSAGES/django.po
19+++ b/django/conf/locale/sv/LC_MESSAGES/django.po
20@@ -6,7 +6,7 @@ msgid ""
21 msgstr ""
22 "Project-Id-Version: Django\n"
23 "Report-Msgid-Bugs-To: \n"
24-"POT-Creation-Date: 2008-09-03 04:36+0200\n"
25+"POT-Creation-Date: 2008-10-03 11:01-0500\n"
26 "PO-Revision-Date: 2008-05-26 11:15+0200\n"
27 "Last-Translator: Ludvig Ericson <ludvig.ericson@gmail.com>\n"
28 "Language-Team: Django I18N <Django-I18N@googlegroups.com>\n"
29@@ -347,30 +347,30 @@ msgid ""
30 msgstr ""
31 "%(name)s \"%(obj)s\" lades till. Du kan redigera objektet igen nedanför."
32 
33-#: contrib/admin/options.py:536
34+#: contrib/admin/options.py:528
35 #, python-format
36 msgid "Add %s"
37 msgstr "Lägg till %s"
38 
39-#: contrib/admin/options.py:614
40+#: contrib/admin/options.py:605
41 #, python-format
42 msgid "Change %s"
43 msgstr "Ändra %s"
44 
45-#: contrib/admin/options.py:646
46+#: contrib/admin/options.py:637
47 msgid "Database error"
48 msgstr "Databasfel"
49 
50-#: contrib/admin/options.py:696
51+#: contrib/admin/options.py:687
52 #, python-format
53 msgid "The %(name)s \"%(obj)s\" was deleted successfully."
54 msgstr "%(name)s \"%(obj)s\" togs bort."
55 
56-#: contrib/admin/options.py:703
57+#: contrib/admin/options.py:694
58 msgid "Are you sure?"
59 msgstr "Är du säker?"
60 
61-#: contrib/admin/options.py:732
62+#: contrib/admin/options.py:723
63 #, python-format
64 msgid "Change history: %s"
65 msgstr "Ändringshistorik: %s"
66@@ -384,11 +384,11 @@ msgstr ""
67 "Var god ange ett korrekt användarnamn och lösenord. Tänk på att skilja "
68 "mellan gemener och versaler."
69 
70-#: contrib/admin/sites.py:227 contrib/admin/views/decorators.py:40
71+#: contrib/admin/sites.py:226 contrib/admin/views/decorators.py:40
72 msgid "Please log in again, because your session has expired."
73 msgstr "Var god logga in igen, eftersom din session har förfallit."
74 
75-#: contrib/admin/sites.py:234 contrib/admin/views/decorators.py:47
76+#: contrib/admin/sites.py:233 contrib/admin/views/decorators.py:47
77 msgid ""
78 "Looks like your browser isn't configured to accept cookies. Please enable "
79 "cookies, reload this page, and try again."
80@@ -396,27 +396,27 @@ msgstr ""
81 "Det verkar som att din webläsare inte är konfigurerad att acceptera cookies. "
82 "Aktivera cookies, ladda om denna sida och försök igen."
83 
84-#: contrib/admin/sites.py:250 contrib/admin/sites.py:256
85+#: contrib/admin/sites.py:249 contrib/admin/sites.py:255
86 #: contrib/admin/views/decorators.py:66
87 msgid "Usernames cannot contain the '@' character."
88 msgstr "Användarnamn får inte innehålla '@'-tecknet."
89 
90-#: contrib/admin/sites.py:253 contrib/admin/views/decorators.py:62
91+#: contrib/admin/sites.py:252 contrib/admin/views/decorators.py:62
92 #, python-format
93 msgid "Your e-mail address is not your username. Try '%s' instead."
94 msgstr "Din e-postadress är inte ditt användarnamn. Försök med '%s' istället."
95 
96-#: contrib/admin/sites.py:313
97+#: contrib/admin/sites.py:312
98 msgid "Site administration"
99 msgstr "Webbplatsadministration"
100 
101-#: contrib/admin/sites.py:326 contrib/admin/templates/admin/login.html:26
102+#: contrib/admin/sites.py:325 contrib/admin/templates/admin/login.html:26
103 #: contrib/admin/templates/registration/password_reset_complete.html:14
104 #: contrib/admin/views/decorators.py:20
105 msgid "Log in"
106 msgstr "Logga in"
107 
108-#: contrib/admin/sites.py:373
109+#: contrib/admin/sites.py:372
110 #, python-format
111 msgid "%s administration"
112 msgstr "Administration av %s"
113@@ -447,11 +447,11 @@ msgstr "Aktuell:"
114 msgid "Change:"
115 msgstr "Ändra:"
116 
117-#: contrib/admin/widgets.py:121
118+#: contrib/admin/widgets.py:123
119 msgid "Lookup"
120 msgstr "Uppslag"
121 
122-#: contrib/admin/widgets.py:228
123+#: contrib/admin/widgets.py:230
124 msgid "Add Another"
125 msgstr "Lägg till ytterligare"
126 
127@@ -904,7 +904,7 @@ msgstr "E-postadress:"
128 msgid "Reset my password"
129 msgstr "Nollställ mitt lösenord"
130 
131-#: contrib/admin/templatetags/admin_list.py:288
132+#: contrib/admin/templatetags/admin_list.py:284
133 msgid "All dates"
134 msgstr "Alla datum"
135 
136@@ -2802,6 +2802,110 @@ msgstr "Telefonnummer måste vara i formatet XXXX-XXXXXX."
137 msgid "Enter a valid postal code in the format XXXXXX"
138 msgstr "Fyll i ett postnummer med formatet XXX XXX."
139 
140+#: contrib/localflavor/se/forms.py:35
141+msgid "Enter a valid Swedish organisation number."
142+msgstr "Fyll i ett giltigt svenskt organisationsnummer."
143+
144+#: contrib/localflavor/se/forms.py:69
145+msgid "Enter a valid Swedish personal identity number."
146+msgstr "Fyll i ett giltigt svenskt personnummer."
147+
148+#: contrib/localflavor/se/forms.py:70
149+msgid "Enter a Swedish personal identity number with 10 digits (YYMMDD-NNNN)."
150+msgstr "Fyll i ett svenskt personnummer med 10 siffror (YYMMDD-NNNN)."
151+
152+#: contrib/localflavor/se/forms.py:71
153+msgid "Co-ordination numbers are not allowed."
154+msgstr "Samordningsnummer är inte tillåtna."
155+
156+#: contrib/localflavor/se/forms.py:110
157+msgid "Enter a Swedish postal code in the format XXXXX."
158+msgstr "Fyll i ett svenskt postnummer med formatet XXXXX."
159+
160+#: contrib/localflavor/se/se_counties.py:16
161+msgid "Stockholm County"
162+msgstr "Stockholms län"
163+
164+#: contrib/localflavor/se/se_counties.py:17
165+msgid "Västerbotten County"
166+msgstr "Västerbottens län"
167+
168+#: contrib/localflavor/se/se_counties.py:18
169+msgid "Norrbotten County"
170+msgstr "Norrbottens län"
171+
172+#: contrib/localflavor/se/se_counties.py:19
173+msgid "Uppsala County"
174+msgstr "Uppsala län"
175+
176+#: contrib/localflavor/se/se_counties.py:20
177+msgid "Södermanland County"
178+msgstr "Södermanlands län"
179+
180+#: contrib/localflavor/se/se_counties.py:21
181+msgid "Östergötland County"
182+msgstr "Östergötlands län"
183+
184+#: contrib/localflavor/se/se_counties.py:22
185+msgid "Jönköping County"
186+msgstr "Jönköpings län"
187+
188+#: contrib/localflavor/se/se_counties.py:23
189+msgid "Kronoberg County"
190+msgstr "Kronobergs län"
191+
192+#: contrib/localflavor/se/se_counties.py:24
193+msgid "Kalmar County"
194+msgstr "Kalmar län"
195+
196+#: contrib/localflavor/se/se_counties.py:25
197+msgid "Gotland County"
198+msgstr "Gotlands län"
199+
200+#: contrib/localflavor/se/se_counties.py:26
201+msgid "Blekinge County"
202+msgstr "Blekinge län"
203+
204+#: contrib/localflavor/se/se_counties.py:27
205+msgid "Skåne County"
206+msgstr "Skåne län"
207+
208+#: contrib/localflavor/se/se_counties.py:28
209+msgid "Halland County"
210+msgstr "Hallands län"
211+
212+#: contrib/localflavor/se/se_counties.py:29
213+msgid "Västra Götaland County"
214+msgstr "Västa Götalands län"
215+
216+#: contrib/localflavor/se/se_counties.py:30
217+msgid "Värmland County"
218+msgstr "Värmlands län"
219+
220+#: contrib/localflavor/se/se_counties.py:31
221+msgid "Örebro County"
222+msgstr "Örebro län"
223+
224+#: contrib/localflavor/se/se_counties.py:32
225+msgid "Västmanland County"
226+msgstr "Västmanlands län"
227+
228+#: contrib/localflavor/se/se_counties.py:33
229+msgid "Dalarna County"
230+msgstr "Dalarnas län"
231+
232+#: contrib/localflavor/se/se_counties.py:34
233+msgid "Gävleborg County"
234+msgstr "Gävleborgs län"
235+
236+#: contrib/localflavor/se/se_counties.py:35
237+msgid "Västernorrland County"
238+msgstr "Västernorrlands län"
239+
240+#: contrib/localflavor/se/se_counties.py:36
241+msgid "Jämtland County"
242+msgstr "Jämtlands län"
243+
244 #: contrib/localflavor/sk/forms.py:30
245 msgid "Enter a postal code in the format XXXXX or XXX XX."
246 msgstr "Fyll i ett postnummer med formatet XXXXX eller XXX XX."
247@@ -3711,7 +3815,7 @@ msgstr ""
248 "Välj ett giltigt alternativ. %(value)s finns inte bland tillgängliga "
249 "alternativ."
250 
251-#: forms/fields.py:697 forms/fields.py:758 forms/models.py:654
252+#: forms/fields.py:697 forms/fields.py:758 forms/models.py:661
253 msgid "Enter a list of values."
254 msgstr "Fyll i en lista med värden."
255 
256@@ -3735,13 +3839,13 @@ msgstr "Sortering"
257 msgid "%(model_name)s with this %(field_label)s already exists."
258 msgstr "%(model_name)s med detta %(field_label)s finns redan."
259 
260-#: forms/models.py:584
261+#: forms/models.py:591
262 msgid "Select a valid choice. That choice is not one of the available choices."
263 msgstr ""
264 "Välj ett giltigt alternativ. Det valet finns inte bland tillgängliga "
265 "alternativ."
266 
267-#: forms/models.py:655
268+#: forms/models.py:662
269 #, python-format
270 msgid "Select a valid choice. %s is not one of the available choices."
271 msgstr ""
272@@ -4317,9 +4421,6 @@ msgstr "%(verbose_name)s togs bort."
273 #~ msgid "This field must be given if %(field)s is not %(value)s"
274 #~ msgstr "Detta fält måste anges om %(field)s inte är %(value)s"
275 
276-#~ msgid "Duplicate values are not allowed."
277-#~ msgstr "Dubbletter är inte tillåtna."
278-
279 #~ msgid "This value must be between %(lower)s and %(upper)s."
280 #~ msgstr "Detta värde måste vara mellan %(lower)s och %(upper)s."
281 
282diff --git a/django/contrib/localflavor/se/__init__.py b/django/contrib/localflavor/se/__init__.py
283new file mode 100644
284index 0000000..e69de29
285diff --git a/django/contrib/localflavor/se/forms.py b/django/contrib/localflavor/se/forms.py
286new file mode 100644
287index 0000000..4f26cc8
288--- /dev/null
289+++ b/django/contrib/localflavor/se/forms.py
290@@ -0,0 +1,164 @@
291+"""
292+Swedish specific Form helpers
293+"""
294+
295+from django import forms
296+from django.utils.translation import ugettext_lazy as _
297+from django.forms.fields import EMPTY_VALUES
298+
299+from utils import *
300+
301+__all__ = ('SECountySelect', 'SEMunicipalitySelect', 'SEOrganisationNumberField', 'SEPersonalIdentityNumberField', 'SEPostalCodeField')
302+
303+
304+class SECountySelect(forms.Select):
305+    """
306+    A Select form widget that uses a list of the Swedish counties (län)
307+    as its choices.
308+
309+    The cleaned value is the official county code -- see
310+    http://en.wikipedia.org/wiki/Counties_of_Sweden for a list.
311+    """
312+
313+    def __init__(self, attrs=None):
314+        from se_counties import COUNTY_CHOICES
315+        super(SECountySelect, self).__init__(attrs=attrs, choices=COUNTY_CHOICES)
316+
317+
318+class SEMunicipalitySelect(forms.Select):
319+    """
320+    A Select form widget that uses a list of the Swedish municipalities
321+    (kommuner) as its choices.
322+
323+    Returns the official municipality code.
324+    """
325+
326+    def __init__(self, attrs=None):
327+        from se_municipalities import MUNICIPALITY_CHOICES
328+        super(SEMunicipalitySelect, self).__init__(attrs, choices=MUNICIPALITY_CHOICES)
329+
330+
331+class SEOrganisationNumberField(forms.CharField):
332+    """
333+    A form field that validates input as a Swedish organisation number
334+    (organisationsnummer).
335+
336+    This fields accepts the same data as SEPersonalIdentityField (for
337+    sole proprietorships (enskild firma)), with the exception of
338+    co-ordination numbers.
339+   
340+    It also accepts ordinary Swedish organisation numbers.
341+
342+    The correct formats are YYMMDD-XXXX and YYMMDDXXXX. YYMMDDXXXX will be
343+    corrected to YYMMDD-XXXX.
344+   
345+    The YYMMDD+XXXX format has the same meaning as for SEPersonalIdentifyNumber
346+    and can only be used if the organisation is a sole proprietorship
347+    (enskildfirma).
348+    """
349+
350+    default_error_messages = {
351+        'invalid': _('Enter a valid Swedish organisation number.'),
352+    }
353+
354+    def clean(self, value):
355+        value = super(SEOrganisationNumberField, self).clean(value)
356+       
357+        if value in EMPTY_VALUES:
358+            return u''
359+       
360+        match = SWEDISH_ID_NUMBER.match(value)
361+        if not match:
362+            raise forms.ValidationError(self.error_messages['invalid'])
363+
364+        gd = match.groupdict()
365+       
366+        # compare the calculated value with the checksum
367+        if id_number_checksum(gd) != int(gd['checksum']):
368+            raise forms.ValidationError(self.error_messages['invalid'])
369+
370+        if not (valid_organisation(gd) or valid_id_birthday(gd, False)):
371+            raise forms.ValidationError(self.error_messages['invalid'])
372+
373+        return format_id_number(gd)
374+
375+
376+class SEPersonalIdentityNumberField(forms.CharField):
377+    """
378+    A form field that validates input as a Swedish personal identity number
379+    (personnummer).
380+
381+    The correct formats are YYMMDD-XXXX, YYMMDD+XXXX and YYMMDDXXXX.
382+    YYMMDDXXXX will be corrected to YYMMDD-XXXX.
383+
384+    \+ indicates that the person is more than 100 years old, which will be
385+    taken into consideration when the date is validated.
386+   
387+    The checksum will be calculated and checked. The birth date is checked
388+    to be a valid date.
389+
390+    By default, co-ordination numbers (samordningsnummer) will be accepted.
391+    To only allow real personal identity numbers, pass the keyword argument
392+    coordination_number=False to the constructor.
393+    """
394+
395+    def __init__(self, *args, **kwargs):
396+        self.coordination_number = kwargs.pop('coordination_number', True)
397+        super(SEPersonalIdentityNumberField, self).__init__(*args, **kwargs)
398+
399+    default_error_messages = {
400+        'invalid': _('Enter a valid Swedish personal identity number.'),
401+        'invalid_length': _('Enter a Swedish personal identity number with 10 digits (YYMMDD-NNNN).'),
402+        'coordination_number': _('Co-ordination numbers are not allowed.'),
403+    }
404+
405+    def clean(self, value):
406+        value = super(SEPersonalIdentityNumberField, self).clean(value)
407+       
408+        if value in EMPTY_VALUES:
409+            return u''
410+       
411+        if LONG_SWEDISH_ID_NUMBER.match(value):
412+            raise forms.ValidationError(self.error_messages['invalid_length'])
413+       
414+        match = SWEDISH_ID_NUMBER.match(value)
415+        if not match:
416+            raise forms.ValidationError(self.error_messages['invalid'])
417+
418+        gd = match.groupdict()
419+       
420+        # compare the calculated value with the checksum
421+        if id_number_checksum(gd) != int(gd['checksum']):
422+            raise forms.ValidationError(self.error_messages['invalid'])
423+
424+        # check for valid birthday   
425+        if not valid_id_birthday(gd):
426+            raise forms.ValidationError(self.error_messages['invalid'])
427+
428+        # make sure that co-ordination numbers do not pass if not allowed
429+        if not self.coordination_number and int(gd['day']) > 60:
430+            raise forms.ValidationError(self.error_messages['coordination_number'])
431
432+        return format_id_number(gd)
433+
434+
435+class SEPostalCodeField(forms.RegexField):
436+    """
437+    A form field that validates input as a Swedish postal code (postnummer).
438+    Valid codes consist of five digits (XXXXX). The number can optionally be
439+    formatted with a space after the third digit (XXX XX).
440+
441+    The cleaned value will never contain the space.
442+    """
443+
444+    default_error_messages = {
445+        'invalid': _('Enter a Swedish postal code in the format XXXXX.'),
446+    }
447+
448+    def __init__(self, *args, **kwargs):
449+        super(SEPostalCodeField, self).__init__(SE_POSTAL_CODE, *args, **kwargs)
450+
451+    def clean(self, value):
452+        return super(SEPostalCodeField, self).clean(value).replace(' ', '')
453+
454+
455diff --git a/django/contrib/localflavor/se/se_counties.py b/django/contrib/localflavor/se/se_counties.py
456new file mode 100644
457index 0000000..0944064
458--- /dev/null
459+++ b/django/contrib/localflavor/se/se_counties.py
460@@ -0,0 +1,37 @@
461+# -*- coding: utf-8 -*-
462+"""
463+A alphabetical list of Swedish counties, sorted by county codes.
464+
465+
466+http://en.wikipedia.org/wiki/Counties_of_Sweden
467+
468+This exists in this standalone file so that it's only imported into memory
469+when explicitly needed.
470+
471+"""
472+
473+from django.utils.translation import ugettext_lazy as _
474+
475+COUNTY_CHOICES = (
476+    ('AB', _(u'Stockholm County')),
477+    ('AC', _(u'Västerbotten County')),
478+    ('BD', _(u'Norrbotten County')),
479+    ('C', _(u'Uppsala County')),
480+    ('D', _(u'Södermanland County')),
481+    ('E', _(u'Östergötland County')),
482+    ('F', _(u'Jönköping County')),
483+    ('G', _(u'Kronoberg County')),
484+    ('H', _(u'Kalmar County')),
485+    ('I', _(u'Gotland County')),
486+    ('K', _(u'Blekinge County')),
487+    ('M', _(u'Skåne County')),
488+    ('N', _(u'Halland County')),
489+    ('O', _(u'Västra Götaland County')),
490+    ('S', _(u'Värmland County')),
491+    ('T', _(u'Örebro County')),
492+    ('U', _(u'Västmanland County')),
493+    ('W', _(u'Dalarna County')),
494+    ('X', _(u'Gävleborg County')),
495+    ('Y', _(u'Västernorrland County')),
496+    ('Z', _(u'Jämtland County')),
497+)
498diff --git a/django/contrib/localflavor/se/se_municipalities.py b/django/contrib/localflavor/se/se_municipalities.py
499new file mode 100644
500index 0000000..2035dda
501--- /dev/null
502+++ b/django/contrib/localflavor/se/se_municipalities.py
503@@ -0,0 +1,305 @@
504+# -*- coding: utf-8 -*-
505+"""
506+An alphabetical list of Swedish municipalities for use as `choices` in a
507+formfield.
508+
509+This exists in this standalone file so that it's only imported into memory
510+when explicitly needed.
511+
512+This list was fetched 2008-10-03 from:
513+http://www.ssd.scb.se/databaser/makro/visavar.asp?yp=duwird&xu=c5587001&lang=2&langdb=2&Fromwhere=S&omradekod=BE&huvudtabell=BefArealTathetKon&innehall=Areal&prodid=BE0101&deltabell=K1&fromSok=&preskat=O
514+
515+"""
516+
517+MUNICIPALITY_CHOICES = (
518+    ('1440', u'Ale'),
519+    ('1489', u'Alingsås'),
520+    ('0764', u'Alvesta'),
521+    ('0604', u'Aneby'),
522+    ('1984', u'Arboga'),
523+    ('2506', u'Arjeplog'),
524+    ('2505', u'Arvidsjaur'),
525+    ('1784', u'Arvika'),
526+    ('1882', u'Askersund'),
527+    ('2084', u'Avesta'),
528+    ('1460', u'Bengtsfors'),
529+    ('2326', u'Berg'),
530+    ('2403', u'Bjurholm'),
531+    ('1260', u'Bjuv'),
532+    ('2582', u'Boden'),
533+    ('1443', u'Bollebygd'),
534+    ('2183', u'Bollnäs'),
535+    ('0885', u'Borgholm'),
536+    ('2081', u'Borlänge'),
537+    ('1490', u'Borås'),
538+    ('0127', u'Botkyrka'),
539+    ('0560', u'Boxholm'),
540+    ('1272', u'Bromölla'),
541+    ('2305', u'Bräcke'),
542+    ('1231', u'Burlöv'),
543+    ('1278', u'Båstad'),
544+    ('1438', u'Dals-Ed'),
545+    ('0162', u'Danderyd'),
546+    ('1862', u'Degerfors'),
547+    ('2425', u'Dorotea'),
548+    ('1730', u'Eda'),
549+    ('0125', u'Ekerö'),
550+    ('0686', u'Eksjö'),
551+    ('0862', u'Emmaboda'),
552+    ('0381', u'Enköping'),
553+    ('0484', u'Eskilstuna'),
554+    ('1285', u'Eslöv'),
555+    ('1445', u'Essunga'),
556+    ('1982', u'Fagersta'),
557+    ('1382', u'Falkenberg'),
558+    ('1499', u'Falköping'),
559+    ('2080', u'Falun'),
560+    ('1782', u'Filipstad'),
561+    ('0562', u'Finspång'),
562+    ('0482', u'Flen'),
563+    ('1763', u'Forshaga'),
564+    ('1439', u'Färgelanda'),
565+    ('2026', u'Gagnef'),
566+    ('0662', u'Gislaved'),
567+    ('0461', u'Gnesta'),
568+    ('0617', u'Gnosjö'),
569+    ('0980', u'Gotland'),
570+    ('1764', u'Grums'),
571+    ('1444', u'Grästorp'),
572+    ('1447', u'Gullspång'),
573+    ('2523', u'Gällivare'),
574+    ('2180', u'Gävle'),
575+    ('1480', u'Göteborg'),
576+    ('1471', u'Götene'),
577+    ('0643', u'Habo'),
578+    ('1783', u'Hagfors'),
579+    ('1861', u'Hallsberg'),
580+    ('1961', u'Hallstahammar'),
581+    ('1380', u'Halmstad'),
582+    ('1761', u'Hammarö'),
583+    ('0136', u'Haninge'),
584+    ('2583', u'Haparanda'),
585+    ('0331', u'Heby'),
586+    ('2083', u'Hedemora'),
587+    ('1283', u'Helsingborg'),
588+    ('1466', u'Herrljunga'),
589+    ('1497', u'Hjo'),
590+    ('2104', u'Hofors'),
591+    ('0126', u'Huddinge'),
592+    ('2184', u'Hudiksvall'),
593+    ('0860', u'Hultsfred'),
594+    ('1315', u'Hylte'),
595+    ('1863', u'Hällefors'),
596+    ('2361', u'Härjedalen'),
597+    ('2280', u'Härnösand'),
598+    ('1401', u'Härryda'),
599+    ('1293', u'Hässleholm'),
600+    ('0305', u'Håbo'),
601+    ('1284', u'Höganäs'),
602+    ('0821', u'Högsby'),
603+    ('1266', u'Hörby'),
604+    ('1267', u'Höör'),
605+    ('2510', u'Jokkmokk'),
606+    ('0123', u'Järfälla'),
607+    ('0680', u'Jönköping'),
608+    ('2514', u'Kalix'),
609+    ('0880', u'Kalmar'),
610+    ('1446', u'Karlsborg'),
611+    ('1082', u'Karlshamn'),
612+    ('1883', u'Karlskoga'),
613+    ('1080', u'Karlskrona'),
614+    ('1780', u'Karlstad'),
615+    ('0483', u'Katrineholm'),
616+    ('1715', u'Kil'),
617+    ('0513', u'Kinda'),
618+    ('2584', u'Kiruna'),
619+    ('1276', u'Klippan'),
620+    ('0330', u'Knivsta'),
621+    ('2282', u'Kramfors'),
622+    ('1290', u'Kristianstad'),
623+    ('1781', u'Kristinehamn'),
624+    ('2309', u'Krokom'),
625+    ('1881', u'Kumla'),
626+    ('1384', u'Kungsbacka'),
627+    ('1960', u'Kungsör'),
628+    ('1482', u'Kungälv'),
629+    ('1261', u'Kävlinge'),
630+    ('1983', u'Köping'),
631+    ('1381', u'Laholm'),
632+    ('1282', u'Landskrona'),
633+    ('1860', u'Laxå'),
634+    ('1814', u'Lekeberg'),
635+    ('2029', u'Leksand'),
636+    ('1441', u'Lerum'),
637+    ('0761', u'Lessebo'),
638+    ('0186', u'Lidingö'),
639+    ('1494', u'Lidköping'),
640+    ('1462', u'Lilla Edet'),
641+    ('1885', u'Lindesberg'),
642+    ('0580', u'Linköping'),
643+    ('0781', u'Ljungby'),
644+    ('2161', u'Ljusdal'),
645+    ('1864', u'Ljusnarsberg'),
646+    ('1262', u'Lomma'),
647+    ('2085', u'Ludvika'),
648+    ('2580', u'Luleå'),
649+    ('1281', u'Lund'),
650+    ('2481', u'Lycksele'),
651+    ('1484', u'Lysekil'),
652+    ('1280', u'Malmö'),
653+    ('2023', u'Malung-Sälen'),
654+    ('2418', u'Malå'),
655+    ('1493', u'Mariestad'),
656+    ('1463', u'Mark'),
657+    ('0767', u'Markaryd'),
658+    ('1461', u'Mellerud'),
659+    ('0586', u'Mjölby'),
660+    ('2062', u'Mora'),
661+    ('0583', u'Motala'),
662+    ('0642', u'Mullsjö'),
663+    ('1430', u'Munkedal'),
664+    ('1762', u'Munkfors'),
665+    ('1481', u'Mölndal'),
666+    ('0861', u'Mönsterås'),
667+    ('0840', u'Mörbylånga'),
668+    ('0182', u'Nacka'),
669+    ('1884', u'Nora'),
670+    ('1962', u'Norberg'),
671+    ('2132', u'Nordanstig'),
672+    ('2401', u'Nordmaling'),
673+    ('0581', u'Norrköping'),
674+    ('0188', u'Norrtälje'),
675+    ('2417', u'Norsjö'),
676+    ('0881', u'Nybro'),
677+    ('0140', u'Nykvarn'),
678+    ('0480', u'Nyköping'),
679+    ('0192', u'Nynäshamn'),
680+    ('0682', u'Nässjö'),
681+    ('2101', u'Ockelbo'),
682+    ('1060', u'Olofström'),
683+    ('2034', u'Orsa'),
684+    ('1421', u'Orust'),
685+    ('1273', u'Osby'),
686+    ('0882', u'Oskarshamn'),
687+    ('2121', u'Ovanåker'),
688+    ('0481', u'Oxelösund'),
689+    ('2521', u'Pajala'),
690+    ('1402', u'Partille'),
691+    ('1275', u'Perstorp'),
692+    ('2581', u'Piteå'),
693+    ('2303', u'Ragunda'),
694+    ('2409', u'Robertsfors'),
695+    ('1081', u'Ronneby'),
696+    ('2031', u'Rättvik'),
697+    ('1981', u'Sala'),
698+    ('0128', u'Salem'),
699+    ('2181', u'Sandviken'),
700+    ('0191', u'Sigtuna'),
701+    ('1291', u'Simrishamn'),
702+    ('1265', u'Sjöbo'),
703+    ('1495', u'Skara'),
704+    ('2482', u'Skellefteå'),
705+    ('1904', u'Skinnskatteberg'),
706+    ('1264', u'Skurup'),
707+    ('1496', u'Skövde'),
708+    ('2061', u'Smedjebacken'),
709+    ('2283', u'Sollefteå'),
710+    ('0163', u'Sollentuna'),
711+    ('0184', u'Solna'),
712+    ('2422', u'Sorsele'),
713+    ('1427', u'Sotenäs'),
714+    ('1230', u'Staffanstorp'),
715+    ('1415', u'Stenungsund'),
716+    ('0180', u'Stockholm'),
717+    ('1760', u'Storfors'),
718+    ('2421', u'Storuman'),
719+    ('0486', u'Strängnäs'),
720+    ('1486', u'Strömstad'),
721+    ('2313', u'Strömsund'),
722+    ('0183', u'Sundbyberg'),
723+    ('2281', u'Sundsvall'),
724+    ('1766', u'Sunne'),
725+    ('1907', u'Surahammar'),
726+    ('1214', u'Svalöv'),
727+    ('1263', u'Svedala'),
728+    ('1465', u'Svenljunga'),
729+    ('1785', u'Säffle'),
730+    ('2082', u'Säter'),
731+    ('0684', u'Sävsjö'),
732+    ('2182', u'Söderhamn'),
733+    ('0582', u'Söderköping'),
734+    ('0181', u'Södertälje'),
735+    ('1083', u'Sölvesborg'),
736+    ('1435', u'Tanum'),
737+    ('1472', u'Tibro'),
738+    ('1498', u'Tidaholm'),
739+    ('0360', u'Tierp'),
740+    ('2262', u'Timrå'),
741+    ('0763', u'Tingsryd'),
742+    ('1419', u'Tjörn'),
743+    ('1270', u'Tomelilla'),
744+    ('1737', u'Torsby'),
745+    ('0834', u'Torsås'),
746+    ('1452', u'Tranemo'),
747+    ('0687', u'Tranås'),
748+    ('1287', u'Trelleborg'),
749+    ('1488', u'Trollhättan'),
750+    ('0488', u'Trosa'),
751+    ('0138', u'Tyresö'),
752+    ('0160', u'Täby'),
753+    ('1473', u'Töreboda'),
754+    ('1485', u'Uddevalla'),
755+    ('1491', u'Ulricehamn'),
756+    ('2480', u'Umeå'),
757+    ('0114', u'Upplands Väsby'),
758+    ('0139', u'Upplands-Bro'),
759+    ('0380', u'Uppsala'),
760+    ('0760', u'Uppvidinge'),
761+    ('0584', u'Vadstena'),
762+    ('0665', u'Vaggeryd'),
763+    ('0563', u'Valdemarsvik'),
764+    ('0115', u'Vallentuna'),
765+    ('2021', u'Vansbro'),
766+    ('1470', u'Vara'),
767+    ('1383', u'Varberg'),
768+    ('0187', u'Vaxholm'),
769+    ('1233', u'Vellinge'),
770+    ('0685', u'Vetlanda'),
771+    ('2462', u'Vilhelmina'),
772+    ('0884', u'Vimmerby'),
773+    ('2404', u'Vindeln'),
774+    ('0428', u'Vingåker'),
775+    ('1487', u'Vänersborg'),
776+    ('2460', u'Vännäs'),
777+    ('0120', u'Värmdö'),
778+    ('0683', u'Värnamo'),
779+    ('0883', u'Västervik'),
780+    ('1980', u'Västerås'),
781+    ('0780', u'Växjö'),
782+    ('1442', u'Vårgårda'),
783+    ('0512', u'Ydre'),
784+    ('1286', u'Ystad'),
785+    ('0765', u'Älmhult'),
786+    ('2039', u'Älvdalen'),
787+    ('0319', u'Älvkarleby'),
788+    ('2560', u'Älvsbyn'),
789+    ('1292', u'Ängelholm'),
790+    ('1492', u'Åmål'),
791+    ('2260', u'Ånge'),
792+    ('2321', u'Åre'),
793+    ('1765', u'Årjäng'),
794+    ('2463', u'Åsele'),
795+    ('1277', u'Åstorp'),
796+    ('0561', u'Åtvidaberg'),
797+    ('1407', u'Öckerö'),
798+    ('0509', u'Ödeshög'),
799+    ('1880', u'Örebro'),
800+    ('1257', u'Örkelljunga'),
801+    ('2284', u'Örnsköldsvik'),
802+    ('2380', u'Östersund'),
803+    ('0117', u'Österåker'),
804+    ('0382', u'Östhammar'),
805+    ('1256', u'Östra Göinge'),
806+    ('2513', u'Överkalix'),
807+    ('2518', u'Övertorneå'),
808+)
809diff --git a/django/contrib/localflavor/se/utils.py b/django/contrib/localflavor/se/utils.py
810new file mode 100644
811index 0000000..f9b3cc6
812--- /dev/null
813+++ b/django/contrib/localflavor/se/utils.py
814@@ -0,0 +1,56 @@
815+import re
816+import time
817+import datetime
818+
819+SWEDISH_ID_NUMBER = re.compile(r'^(?P<year>\d{2})(?P<month>\d{2})(?P<day>\d{2})(?P<sign>[\-+]?)(?P<serial>\d{3})(?P<checksum>\d)$')
820+LONG_SWEDISH_ID_NUMBER = re.compile(r'^\d{8}[\-+]?\d{4}$')
821+SE_POSTAL_CODE = re.compile(r'^[1-9]\d{2} ?\d{2}$')
822+
823+def id_number_checksum(gd):
824+    """
825+    Calculates a Swedish id number checksum 
826+    """
827+
828+    n = s = 0
829+    for c in (gd['year'] + gd['month'] + gd['day'] + gd['serial']):
830+        tmp = ((n % 2) and 1 or 2) * int(c)
831+        if tmp > 9:
832+            tmp = sum([int(i) for i in str(tmp)])
833+
834+        s += tmp
835+        n += 1
836
837+    return (((s / 10) + 1) * 10) - s
838+
839+def valid_id_birthday(gd, fix_coordination_number_day=True):
840+
841+    day = int(gd['day'])
842+    if fix_coordination_number_day and day > 60:
843+        day -= 60
844+
845+    current_year = datetime.date.today().year
846+    year = int(time.strftime('%Y')) - int(time.strftime('%y')) + int(gd['year'])
847+   
848+    if ('%s%s%02d' % (gd['year'], gd['month'], day)) > time.strftime('%y%m%d'):
849+        year -= 100
850+
851+    # if the person is older than 100 years
852+    if gd['sign'] == '+':
853+        year -= 100
854+
855+    # Make sure it is a valid date
856+    try:
857+        datetime.date(year, int(gd['month']), day)
858+        return True
859+    except ValueError:
860+        return False
861+
862+def format_id_number(gd):
863+    if not gd['sign']:
864+        gd['sign'] = '-'
865+
866+    return unicode(gd['year'] + gd['month'] + gd['day'] + gd['sign'] + gd['serial'] + gd['checksum'])
867+
868+def valid_organisation(gd):
869+    return int(gd['month']) >= 20 and gd['sign'] in ('-', '')
870+
871diff --git a/docs/ref/contrib/localflavor.txt b/docs/ref/contrib/localflavor.txt
872index 6771efc..a6b6525 100644
873--- a/docs/ref/contrib/localflavor.txt
874+++ b/docs/ref/contrib/localflavor.txt
875@@ -60,6 +60,7 @@ Countries currently supported by :mod:`~django.contrib.localflavor` are:
876     * Slovakia_
877     * `South Africa`_
878     * Spain_
879+    * Sweden_
880     * Switzerland_
881     * `United Kingdom`_
882     * `United States of America`_
883@@ -99,6 +100,7 @@ Here's an example of how to use them::
884 .. _Slovakia: `Slovakia (sk)`_
885 .. _South Africa: `South Africa (za)`_
886 .. _Spain: `Spain (es)`_
887+.. _Sweden: `Sweden (se)`_
888 .. _Switzerland: `Switzerland (ch)`_
889 .. _United Kingdom: `United Kingdom (uk)`_
890 .. _United States of America: `United States of America (us)`_
891@@ -573,6 +575,68 @@ Spain (``es``)
892 
893     A ``Select`` widget that uses a list of Spanish regions as its choices.
894 
895+Sweden (``se``)
896+===============
897+
898+.. class:: se.forms.SECountySelect
899+
900+    A Select form widget that uses a list of the Swedish counties (län)
901+    as its choices.
902+
903+    The cleaned value is the official county code -- see
904+    http://en.wikipedia.org/wiki/Counties_of_Sweden for a list.
905+
906+.. class:: se.forms.SEMunicipalitySelect
907+
908+    A Select form widget that uses a list of the Swedish municipalities
909+    (kommuner) as its choices.
910+
911+    Returns the official municipality code.
912+
913+.. class:: se.forms.SEOrganisationNumber
914+
915+    A form field that validates input as a Swedish organisation number
916+    (organisationsnummer).
917+
918+    This fields accepts the same data as SEPersonalIdentityField (for
919+    sole proprietorships (enskild firma)), with the exception of
920+    co-ordination numbers.
921+   
922+    It also accepts ordinary Swedish organisation numbers.
923+
924+    The correct formats are YYMMDD-XXXX and YYMMDDXXXX. YYMMDDXXXX will be
925+    corrected to YYMMDD-XXXX.
926+   
927+    The YYMMDD+XXXX format has the same meaning as for SEPersonalIdentifyNumber
928+    and can only be used if the organisation is a sole proprietorship
929+    (enskildfirma).
930+
931+.. class:: se.forms.SEPersonalIdentityNumber
932+
933+    A form field that validates input as a Swedish personal identity number
934+    (personnummer).
935+
936+    The correct formats are YYMMDD-XXXX, YYMMDD+XXXX and YYMMDDXXXX.
937+    YYMMDDXXXX will be corrected to YYMMDD-XXXX.
938+
939+    \+ indicates that the person is more than 100 years old, which will be
940+    taken into consideration when the date is validated.
941+   
942+    The checksum will be calculated and checked. The birth date is checked
943+    to be a valid date.
944+
945+    By default, co-ordination numbers (samordningsnummer) will be accepted.
946+    To only allow real personal identity numbers, pass the keyword argument
947+    coordination_number=False to the constructor.
948+
949+.. class:: se.forms.SEPostalCodeField
950+
951+    A form field that validates input as a Swedish postal code (postnummer).
952+    Valid codes consist of five digits (XXXXX). The number can optionally be
953+    formatted with a space after the third digit (XXX XX).
954+
955+    The cleaned value will never contain the space.
956+
957 Switzerland (``ch``)
958 ====================
959 
960diff --git a/tests/regressiontests/forms/localflavor/se.py b/tests/regressiontests/forms/localflavor/se.py
961new file mode 100644
962index 0000000..99553c7
963--- /dev/null
964+++ b/tests/regressiontests/forms/localflavor/se.py
965@@ -0,0 +1,300 @@
966+# -*- coding: utf-8 -*-
967+# Tests for the contrib/localflavor/se form fields.
968+
969+tests = r"""
970+
971+# SECountySelect #####################################################
972+>>> from django.contrib.localflavor.se.forms import SECountySelect
973+
974+>>> w = SECountySelect()
975+>>> w.render('swedish_county', 'E')
976+u'<select name="swedish_county">\n<option value="AB">Stockholm County</option>\n<option value="AC">V\xe4sterbotten County</option>\n<option value="BD">Norrbotten County</option>\n<option value="C">Uppsala County</option>\n<option value="D">S\xf6dermanland County</option>\n<option value="E" selected="selected">\xd6sterg\xf6tland County</option>\n<option value="F">J\xf6nk\xf6ping County</option>\n<option value="G">Kronoberg County</option>\n<option value="H">Kalmar County</option>\n<option value="I">Gotland County</option>\n<option value="K">Blekinge County</option>\n<option value="M">Sk\xe5ne County</option>\n<option value="N">Halland County</option>\n<option value="O">V\xe4stra G\xf6taland County</option>\n<option value="S">V\xe4rmland County</option>\n<option value="T">\xd6rebro County</option>\n<option value="U">V\xe4stmanland County</option>\n<option value="W">Dalarna County</option>\n<option value="X">G\xe4vleborg County</option>\n<option value="Y">V\xe4sternorrland County</option>\n<option value="Z">J\xe4mtland County</option>\n</select>'
977+
978+>>> from django.contrib.localflavor.se.forms import SEMunicipalitySelect
979+>>> w = SEMunicipalitySelect()
980+>>> w.render('swedish_municipalities', '0580')
981+u'<select name="swedish_municipalities">\n<option value="1440">Ale</option>\n<option value="1489">Alings\xe5s</option>\n<option value="0764">Alvesta</option>\n<option value="0604">Aneby</option>\n<option value="1984">Arboga</option>\n<option value="2506">Arjeplog</option>\n<option value="2505">Arvidsjaur</option>\n<option value="1784">Arvika</option>\n<option value="1882">Askersund</option>\n<option value="2084">Avesta</option>\n<option value="1460">Bengtsfors</option>\n<option value="2326">Berg</option>\n<option value="2403">Bjurholm</option>\n<option value="1260">Bjuv</option>\n<option value="2582">Boden</option>\n<option value="1443">Bollebygd</option>\n<option value="2183">Bolln\xe4s</option>\n<option value="0885">Borgholm</option>\n<option value="2081">Borl\xe4nge</option>\n<option value="1490">Bor\xe5s</option>\n<option value="0127">Botkyrka</option>\n<option value="0560">Boxholm</option>\n<option value="1272">Brom\xf6lla</option>\n<option value="2305">Br\xe4cke</option>\n<option value="1231">Burl\xf6v</option>\n<option value="1278">B\xe5stad</option>\n<option value="1438">Dals-Ed</option>\n<option value="0162">Danderyd</option>\n<option value="1862">Degerfors</option>\n<option value="2425">Dorotea</option>\n<option value="1730">Eda</option>\n<option value="0125">Eker\xf6</option>\n<option value="0686">Eksj\xf6</option>\n<option value="0862">Emmaboda</option>\n<option value="0381">Enk\xf6ping</option>\n<option value="0484">Eskilstuna</option>\n<option value="1285">Esl\xf6v</option>\n<option value="1445">Essunga</option>\n<option value="1982">Fagersta</option>\n<option value="1382">Falkenberg</option>\n<option value="1499">Falk\xf6ping</option>\n<option value="2080">Falun</option>\n<option value="1782">Filipstad</option>\n<option value="0562">Finsp\xe5ng</option>\n<option value="0482">Flen</option>\n<option value="1763">Forshaga</option>\n<option value="1439">F\xe4rgelanda</option>\n<option value="2026">Gagnef</option>\n<option value="0662">Gislaved</option>\n<option value="0461">Gnesta</option>\n<option value="0617">Gnosj\xf6</option>\n<option value="0980">Gotland</option>\n<option value="1764">Grums</option>\n<option value="1444">Gr\xe4storp</option>\n<option value="1447">Gullsp\xe5ng</option>\n<option value="2523">G\xe4llivare</option>\n<option value="2180">G\xe4vle</option>\n<option value="1480">G\xf6teborg</option>\n<option value="1471">G\xf6tene</option>\n<option value="0643">Habo</option>\n<option value="1783">Hagfors</option>\n<option value="1861">Hallsberg</option>\n<option value="1961">Hallstahammar</option>\n<option value="1380">Halmstad</option>\n<option value="1761">Hammar\xf6</option>\n<option value="0136">Haninge</option>\n<option value="2583">Haparanda</option>\n<option value="0331">Heby</option>\n<option value="2083">Hedemora</option>\n<option value="1283">Helsingborg</option>\n<option value="1466">Herrljunga</option>\n<option value="1497">Hjo</option>\n<option value="2104">Hofors</option>\n<option value="0126">Huddinge</option>\n<option value="2184">Hudiksvall</option>\n<option value="0860">Hultsfred</option>\n<option value="1315">Hylte</option>\n<option value="1863">H\xe4llefors</option>\n<option value="2361">H\xe4rjedalen</option>\n<option value="2280">H\xe4rn\xf6sand</option>\n<option value="1401">H\xe4rryda</option>\n<option value="1293">H\xe4ssleholm</option>\n<option value="0305">H\xe5bo</option>\n<option value="1284">H\xf6gan\xe4s</option>\n<option value="0821">H\xf6gsby</option>\n<option value="1266">H\xf6rby</option>\n<option value="1267">H\xf6\xf6r</option>\n<option value="2510">Jokkmokk</option>\n<option value="0123">J\xe4rf\xe4lla</option>\n<option value="0680">J\xf6nk\xf6ping</option>\n<option value="2514">Kalix</option>\n<option value="0880">Kalmar</option>\n<option value="1446">Karlsborg</option>\n<option value="1082">Karlshamn</option>\n<option value="1883">Karlskoga</option>\n<option value="1080">Karlskrona</option>\n<option value="1780">Karlstad</option>\n<option value="0483">Katrineholm</option>\n<option value="1715">Kil</option>\n<option value="0513">Kinda</option>\n<option value="2584">Kiruna</option>\n<option value="1276">Klippan</option>\n<option value="0330">Knivsta</option>\n<option value="2282">Kramfors</option>\n<option value="1290">Kristianstad</option>\n<option value="1781">Kristinehamn</option>\n<option value="2309">Krokom</option>\n<option value="1881">Kumla</option>\n<option value="1384">Kungsbacka</option>\n<option value="1960">Kungs\xf6r</option>\n<option value="1482">Kung\xe4lv</option>\n<option value="1261">K\xe4vlinge</option>\n<option value="1983">K\xf6ping</option>\n<option value="1381">Laholm</option>\n<option value="1282">Landskrona</option>\n<option value="1860">Lax\xe5</option>\n<option value="1814">Lekeberg</option>\n<option value="2029">Leksand</option>\n<option value="1441">Lerum</option>\n<option value="0761">Lessebo</option>\n<option value="0186">Liding\xf6</option>\n<option value="1494">Lidk\xf6ping</option>\n<option value="1462">Lilla Edet</option>\n<option value="1885">Lindesberg</option>\n<option value="0580" selected="selected">Link\xf6ping</option>\n<option value="0781">Ljungby</option>\n<option value="2161">Ljusdal</option>\n<option value="1864">Ljusnarsberg</option>\n<option value="1262">Lomma</option>\n<option value="2085">Ludvika</option>\n<option value="2580">Lule\xe5</option>\n<option value="1281">Lund</option>\n<option value="2481">Lycksele</option>\n<option value="1484">Lysekil</option>\n<option value="1280">Malm\xf6</option>\n<option value="2023">Malung-S\xe4len</option>\n<option value="2418">Mal\xe5</option>\n<option value="1493">Mariestad</option>\n<option value="1463">Mark</option>\n<option value="0767">Markaryd</option>\n<option value="1461">Mellerud</option>\n<option value="0586">Mj\xf6lby</option>\n<option value="2062">Mora</option>\n<option value="0583">Motala</option>\n<option value="0642">Mullsj\xf6</option>\n<option value="1430">Munkedal</option>\n<option value="1762">Munkfors</option>\n<option value="1481">M\xf6lndal</option>\n<option value="0861">M\xf6nster\xe5s</option>\n<option value="0840">M\xf6rbyl\xe5nga</option>\n<option value="0182">Nacka</option>\n<option value="1884">Nora</option>\n<option value="1962">Norberg</option>\n<option value="2132">Nordanstig</option>\n<option value="2401">Nordmaling</option>\n<option value="0581">Norrk\xf6ping</option>\n<option value="0188">Norrt\xe4lje</option>\n<option value="2417">Norsj\xf6</option>\n<option value="0881">Nybro</option>\n<option value="0140">Nykvarn</option>\n<option value="0480">Nyk\xf6ping</option>\n<option value="0192">Nyn\xe4shamn</option>\n<option value="0682">N\xe4ssj\xf6</option>\n<option value="2101">Ockelbo</option>\n<option value="1060">Olofstr\xf6m</option>\n<option value="2034">Orsa</option>\n<option value="1421">Orust</option>\n<option value="1273">Osby</option>\n<option value="0882">Oskarshamn</option>\n<option value="2121">Ovan\xe5ker</option>\n<option value="0481">Oxel\xf6sund</option>\n<option value="2521">Pajala</option>\n<option value="1402">Partille</option>\n<option value="1275">Perstorp</option>\n<option value="2581">Pite\xe5</option>\n<option value="2303">Ragunda</option>\n<option value="2409">Robertsfors</option>\n<option value="1081">Ronneby</option>\n<option value="2031">R\xe4ttvik</option>\n<option value="1981">Sala</option>\n<option value="0128">Salem</option>\n<option value="2181">Sandviken</option>\n<option value="0191">Sigtuna</option>\n<option value="1291">Simrishamn</option>\n<option value="1265">Sj\xf6bo</option>\n<option value="1495">Skara</option>\n<option value="2482">Skellefte\xe5</option>\n<option value="1904">Skinnskatteberg</option>\n<option value="1264">Skurup</option>\n<option value="1496">Sk\xf6vde</option>\n<option value="2061">Smedjebacken</option>\n<option value="2283">Sollefte\xe5</option>\n<option value="0163">Sollentuna</option>\n<option value="0184">Solna</option>\n<option value="2422">Sorsele</option>\n<option value="1427">Soten\xe4s</option>\n<option value="1230">Staffanstorp</option>\n<option value="1415">Stenungsund</option>\n<option value="0180">Stockholm</option>\n<option value="1760">Storfors</option>\n<option value="2421">Storuman</option>\n<option value="0486">Str\xe4ngn\xe4s</option>\n<option value="1486">Str\xf6mstad</option>\n<option value="2313">Str\xf6msund</option>\n<option value="0183">Sundbyberg</option>\n<option value="2281">Sundsvall</option>\n<option value="1766">Sunne</option>\n<option value="1907">Surahammar</option>\n<option value="1214">Sval\xf6v</option>\n<option value="1263">Svedala</option>\n<option value="1465">Svenljunga</option>\n<option value="1785">S\xe4ffle</option>\n<option value="2082">S\xe4ter</option>\n<option value="0684">S\xe4vsj\xf6</option>\n<option value="2182">S\xf6derhamn</option>\n<option value="0582">S\xf6derk\xf6ping</option>\n<option value="0181">S\xf6dert\xe4lje</option>\n<option value="1083">S\xf6lvesborg</option>\n<option value="1435">Tanum</option>\n<option value="1472">Tibro</option>\n<option value="1498">Tidaholm</option>\n<option value="0360">Tierp</option>\n<option value="2262">Timr\xe5</option>\n<option value="0763">Tingsryd</option>\n<option value="1419">Tj\xf6rn</option>\n<option value="1270">Tomelilla</option>\n<option value="1737">Torsby</option>\n<option value="0834">Tors\xe5s</option>\n<option value="1452">Tranemo</option>\n<option value="0687">Tran\xe5s</option>\n<option value="1287">Trelleborg</option>\n<option value="1488">Trollh\xe4ttan</option>\n<option value="0488">Trosa</option>\n<option value="0138">Tyres\xf6</option>\n<option value="0160">T\xe4by</option>\n<option value="1473">T\xf6reboda</option>\n<option value="1485">Uddevalla</option>\n<option value="1491">Ulricehamn</option>\n<option value="2480">Ume\xe5</option>\n<option value="0114">Upplands V\xe4sby</option>\n<option value="0139">Upplands-Bro</option>\n<option value="0380">Uppsala</option>\n<option value="0760">Uppvidinge</option>\n<option value="0584">Vadstena</option>\n<option value="0665">Vaggeryd</option>\n<option value="0563">Valdemarsvik</option>\n<option value="0115">Vallentuna</option>\n<option value="2021">Vansbro</option>\n<option value="1470">Vara</option>\n<option value="1383">Varberg</option>\n<option value="0187">Vaxholm</option>\n<option value="1233">Vellinge</option>\n<option value="0685">Vetlanda</option>\n<option value="2462">Vilhelmina</option>\n<option value="0884">Vimmerby</option>\n<option value="2404">Vindeln</option>\n<option value="0428">Ving\xe5ker</option>\n<option value="1487">V\xe4nersborg</option>\n<option value="2460">V\xe4nn\xe4s</option>\n<option value="0120">V\xe4rmd\xf6</option>\n<option value="0683">V\xe4rnamo</option>\n<option value="0883">V\xe4stervik</option>\n<option value="1980">V\xe4ster\xe5s</option>\n<option value="0780">V\xe4xj\xf6</option>\n<option value="1442">V\xe5rg\xe5rda</option>\n<option value="0512">Ydre</option>\n<option value="1286">Ystad</option>\n<option value="0765">\xc4lmhult</option>\n<option value="2039">\xc4lvdalen</option>\n<option value="0319">\xc4lvkarleby</option>\n<option value="2560">\xc4lvsbyn</option>\n<option value="1292">\xc4ngelholm</option>\n<option value="1492">\xc5m\xe5l</option>\n<option value="2260">\xc5nge</option>\n<option value="2321">\xc5re</option>\n<option value="1765">\xc5rj\xe4ng</option>\n<option value="2463">\xc5sele</option>\n<option value="1277">\xc5storp</option>\n<option value="0561">\xc5tvidaberg</option>\n<option value="1407">\xd6cker\xf6</option>\n<option value="0509">\xd6desh\xf6g</option>\n<option value="1880">\xd6rebro</option>\n<option value="1257">\xd6rkelljunga</option>\n<option value="2284">\xd6rnsk\xf6ldsvik</option>\n<option value="2380">\xd6stersund</option>\n<option value="0117">\xd6ster\xe5ker</option>\n<option value="0382">\xd6sthammar</option>\n<option value="1256">\xd6stra G\xf6inge</option>\n<option value="2513">\xd6verkalix</option>\n<option value="2518">\xd6vertorne\xe5</option>\n</select>'
982+
983+
984+
985+
986+# SEOrganisationNumberField #######################################
987+
988+>>> from django.contrib.localflavor.se.forms import SEOrganisationNumberField
989+
990+>>> f = SEOrganisationNumberField()
991+
992+# Check ordinary personal identity numbers first
993+>>> f.clean('870512-1989')
994+u'870512-1989'
995+>>> f.clean('870512-2128')
996+u'870512-2128'
997+>>> f.clean('081015-6315')
998+u'081015-6315'
999+>>> f.clean('081015+6315')
1000+u'081015+6315'
1001+>>> f.clean('0810156315')
1002+u'081015-6315'
1003+>>> f.clean('081015 6315')
1004+Traceback (most recent call last):
1005+...
1006+ValidationError: [u'Enter a valid Swedish organisation number.']
1007+
1008+>>> f.clean('950231-4496')
1009+Traceback (most recent call last):
1010+...
1011+ValidationError: [u'Enter a valid Swedish organisation number.']
1012+
1013+Invalid date - month 14
1014+>>> f.clean('6914104499')
1015+Traceback (most recent call last):
1016+...
1017+ValidationError: [u'Enter a valid Swedish organisation number.']
1018+
1019+No special treatment for 12 (four year digits) digits
1020+>>> f.clean('19870512-1989')
1021+Traceback (most recent call last):
1022+...
1023+ValidationError: [u'Enter a valid Swedish organisation number.']
1024+
1025+# Invalid value
1026+>>> f.clean('950d314496')
1027+Traceback (most recent call last):
1028+...
1029+ValidationError: [u'Enter a valid Swedish organisation number.']
1030+
1031+>>> f.clean('invalid!!!')
1032+Traceback (most recent call last):
1033+...
1034+ValidationError: [u'Enter a valid Swedish organisation number.']
1035+
1036+# Invalid checksum
1037+>>> f.clean('870514-1111')
1038+Traceback (most recent call last):
1039+...
1040+ValidationError: [u'Enter a valid Swedish organisation number.']
1041+
1042+# Empty values
1043+>>> f.clean('')
1044+Traceback (most recent call last):
1045+...
1046+ValidationError: [u'This field is required.']
1047+
1048+>>> f.clean(None)
1049+Traceback (most recent call last):
1050+...
1051+ValidationError: [u'This field is required.']
1052+
1053+# Co-ordination number checking
1054+# Co-ordination numbers are not valid organisation numbers
1055+
1056+>>> f.clean('870574-1315')
1057+Traceback (most recent call last):
1058+...
1059+ValidationError: [u'Enter a valid Swedish organisation number.']
1060+
1061+>>> f.clean('870573-1311')
1062+Traceback (most recent call last):
1063+...
1064+ValidationError: [u'Enter a valid Swedish organisation number.']
1065+
1066+# Test some different organisation numbers
1067+>>> f.clean('556074-7569') # IKEA Linköping
1068+u'556074-7569'
1069+
1070+>>> f.clean('556074-3089') # Volvo Personvagnar
1071+u'556074-3089'
1072+
1073+>>> f.clean('822001-5476') # LJS (organisation)
1074+u'822001-5476'
1075+
1076+>>> f.clean('8220015476') # LJS (organisation)
1077+u'822001-5476'
1078+
1079+>>> f.clean('212000-0449') # Katedralskolan Linköping (school)
1080+u'212000-0449'
1081+
1082+>>> f.clean('556074+3089') # Volvo Personvagnar, bad formatting
1083+Traceback (most recent call last):
1084+...
1085+ValidationError: [u'Enter a valid Swedish organisation number.']
1086+
1087+
1088+# Empty values with required=False
1089+>>> f = SEOrganisationNumberField(required=False)
1090+
1091+>>> f.clean(None)
1092+u''
1093+
1094+>>> f.clean('')
1095+u''
1096+
1097+
1098+
1099+# SEPersonalIdentityNumberField #######################################
1100+
1101+>>> from django.contrib.localflavor.se.forms import SEPersonalIdentityNumberField
1102+
1103+>>> f = SEPersonalIdentityNumberField()
1104+>>> f.clean('870512-1989')
1105+u'870512-1989'
1106+
1107+>>> f.clean('870512-2128')
1108+u'870512-2128'
1109+
1110+The date and the extra numbers can be separated by - or +
1111+>>> f.clean('081015-6315')
1112+u'081015-6315'
1113+
1114+>>> f.clean('081015+6315')
1115+u'081015+6315'
1116+
1117+>>> f.clean('0810156315')
1118+u'081015-6315'
1119+
1120+Separation by space are not allowed
1121+>>> f.clean('081015 6315')
1122+Traceback (most recent call last):
1123+...
1124+ValidationError: [u'Enter a valid Swedish personal identity number.']
1125+
1126+February 31st does not exist
1127+>>> f.clean('950231-4496')
1128+Traceback (most recent call last):
1129+...
1130+ValidationError: [u'Enter a valid Swedish personal identity number.']
1131+
1132+Invalid date - month 14
1133+>>> f.clean('6914104499')
1134+Traceback (most recent call last):
1135+...
1136+ValidationError: [u'Enter a valid Swedish personal identity number.']
1137+
1138+12 (four year digits) digit numbers are not allowed
1139+>>> f.clean('19870512-1989')
1140+Traceback (most recent call last):
1141+...
1142+ValidationError: [u'Enter a Swedish personal identity number with 10 digits (YYMMDD-NNNN).']
1143+
1144+# Invalid value
1145+>>> f.clean('950d314496')
1146+Traceback (most recent call last):
1147+...
1148+ValidationError: [u'Enter a valid Swedish personal identity number.']
1149+
1150+>>> f.clean('invalid!!!')
1151+Traceback (most recent call last):
1152+...
1153+ValidationError: [u'Enter a valid Swedish personal identity number.']
1154+
1155+# Invalid checksum
1156+>>> f.clean('870514-1111')
1157+Traceback (most recent call last):
1158+...
1159+ValidationError: [u'Enter a valid Swedish personal identity number.']
1160+
1161+# Empty values
1162+>>> f.clean('')
1163+Traceback (most recent call last):
1164+...
1165+ValidationError: [u'This field is required.']
1166+
1167+>>> f.clean(None)
1168+Traceback (most recent call last):
1169+...
1170+ValidationError: [u'This field is required.']
1171+
1172+# Co-ordination number checking
1173+>>> f.clean('870574-1315')
1174+u'870574-1315'
1175+
1176+>>> f.clean('870574+1315')
1177+u'870574+1315'
1178+
1179+>>> f.clean('870573-1311')
1180+Traceback (most recent call last):
1181+...
1182+ValidationError: [u'Enter a valid Swedish personal identity number.']
1183+
1184+# Check valid co-ordination numbers, that should not be accepted
1185+# because of coordination_number=False
1186+>>> f = SEPersonalIdentityNumberField(coordination_number=False)
1187+
1188+>>> f.clean('870574-1315')
1189+Traceback (most recent call last):
1190+...
1191+ValidationError: [u'Co-ordination numbers are not allowed.']
1192+
1193+>>> f.clean('870574+1315')
1194+Traceback (most recent call last):
1195+...
1196+ValidationError: [u'Co-ordination numbers are not allowed.']
1197+
1198+>>> f.clean('8705741315')
1199+Traceback (most recent call last):
1200+...
1201+ValidationError: [u'Co-ordination numbers are not allowed.']
1202+
1203+# Invalid co-ordination numbers should be treated as invalid, and not
1204+# as co-ordination numbers
1205+>>> f.clean('870573-1311')
1206+Traceback (most recent call last):
1207+...
1208+ValidationError: [u'Enter a valid Swedish personal identity number.']
1209+
1210+# Empty values with required=False
1211+>>> f = SEPersonalIdentityNumberField(required=False)
1212+
1213+>>> f.clean(None)
1214+u''
1215+
1216+>>> f.clean('')
1217+u''
1218+
1219+# SEPostalCodeField ###############################################
1220+>>> from django.contrib.localflavor.se.forms import SEPostalCodeField
1221+>>> f = SEPostalCodeField()
1222+>>>
1223+Postal codes can have spaces
1224+>>> f.clean('589 37')
1225+u'58937'
1226+
1227+... but the dont have to
1228+>>> f.clean('58937')
1229+u'58937'
1230+>>> f.clean('abcasfassadf')
1231+Traceback (most recent call last):
1232+...
1233+ValidationError: [u'Enter a Swedish postal code in the format XXXXX.']
1234+
1235+# Only one space is allowed for separation
1236+>>> f.clean('589  37')
1237+Traceback (most recent call last):
1238+...
1239+ValidationError: [u'Enter a Swedish postal code in the format XXXXX.']
1240+
1241+# The postal code must not start with 0
1242+>>> f.clean('01234')
1243+Traceback (most recent call last):
1244+...
1245+ValidationError: [u'Enter a Swedish postal code in the format XXXXX.']
1246+
1247+# Empty values
1248+>>> f.clean('')
1249+Traceback (most recent call last):
1250+...
1251+ValidationError: [u'This field is required.']
1252+
1253+>>> f.clean(None)
1254+Traceback (most recent call last):
1255+...
1256+ValidationError: [u'This field is required.']
1257+
1258+# Empty values, required=False
1259+>>> f = SEPostalCodeField(required=False)
1260+>>> f.clean('')
1261+u''
1262+>>> f.clean(None)
1263+u''
1264+
1265+"""
1266diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py
1267index 6a8b017..f930003 100644
1268--- a/tests/regressiontests/forms/tests.py
1269+++ b/tests/regressiontests/forms/tests.py
1270@@ -21,6 +21,7 @@ from localflavor.jp import tests as localflavor_jp_tests
1271 from localflavor.nl import tests as localflavor_nl_tests
1272 from localflavor.pl import tests as localflavor_pl_tests
1273 from localflavor.ro import tests as localflavor_ro_tests
1274+from localflavor.se import tests as localflavor_se_tests
1275 from localflavor.sk import tests as localflavor_sk_tests
1276 from localflavor.uk import tests as localflavor_uk_tests
1277 from localflavor.us import tests as localflavor_us_tests
1278@@ -54,6 +55,7 @@ __test__ = {
1279     'localflavor_nl_tests': localflavor_nl_tests,
1280     'localflavor_pl_tests': localflavor_pl_tests,
1281     'localflavor_ro_tests': localflavor_ro_tests,
1282+    'localflavor_se_tests': localflavor_se_tests,
1283     'localflavor_sk_tests': localflavor_sk_tests,
1284     'localflavor_uk_tests': localflavor_uk_tests,
1285     'localflavor_us_tests': localflavor_us_tests,