function personnummer(nr){
this.valid=false;
if(!nr.match(/^(\d{2})(\d{2})(\d{2})\-(\d{4})$/)){ return false; }
this.now=new Date(); this.nowFullYear=this.now.getFullYear()+""; this.nowCentury=this.nowFullYear.substring(0,2); this.nowShortYear=this.nowFullYear.substring(2,4);
this.year=RegExp.$1; this.month=RegExp.$2; this.day=RegExp.$3; this.controldigits=RegExp.$4;
this.fullYear=(this.year*1<=this.nowShortYear*1)?(this.nowCentury+this.year)*1:((this.nowCentury*1-1)+this.year)*1;
var months = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
if(this.fullYear%400==0||this.fullYear%4==0&&this.fullYear%100!=0){ months[1]=29; }
if(this.month*1<1||this.month*1>12||this.day*1<1||this.day*1>months[this.month*1-1]){ return false; }
this.alldigits=this.year+this.month+this.day+this.controldigits;
var nn="";
for(var n=0;n<this.alldigits.length;n++){ nn+=((((n+1)%2)+1)*this.alldigits.substring(n,n+1)); }
this.checksum=0;
for(var n=0;n<nn.length;n++){ this.checksum+=nn.substring(n,n+1)*1; }
this.valid=(this.checksum%10==0)?true:false;
this.sex=parseInt(this.controldigits.substring(2,3))%2;
}
han hanterar personnummret som ett objekt, han refererar till personnummret med this (engelska för detta.) när han anropar funktionen så frågar han efter objektets valid egenskap. Denna sätts till false från början för att senare i koden sättas till true om personnummret stämmer.
Efter dett kör han en matchning mot ett reguljärt uttryck (regular expression).
if(!nr.match(/^(\d{2})(\d{2})(\d{2})\-(\d{4})$/)){ return false; }
om nummret inte stämmer överens med mönstret som är: 2 siffror, följt av 2 siffror, följt av ytterligare 2 siffror ett bindestreck och sedan 4 siffror, returnerar funktionen false. Om den däremot stämmer överens lagras sifferföljderna i Regexp-objektet och kan nås genom att använde RegExp.$n. där n är ett heltal och RegExp.$1 motsvarar de två första siffrorna i personnummret osv. Dessa värden skickar han sedan vidare till this-objektet.
Innan han tilldelar dessa värden till this-objektet anropar han JavaScripts inbyggda Date-objekt för att plocka ut ett år med fyra siffror, hämta ut vilket sekel det är (de första två siffrorna i fyrtalsåret), sedan plockar han även ut året i "kortform". Alltså de två sista siffrorna i fyrtalsåret. All "urplockning" sker med egenskapen substring, vilket returnerar en sträng vars längd bestäms av de siffror som du anger inom parenteserna efter substring. Detta för att kunna jämföra med inskrivet värde samt att kunna avgöra om det är skottår.
Det är alltså det som sker på dessa två rader:
this.year=RegExp.$1; this.month=RegExp.$2; this.day=RegExp.$3; this.controldigits=RegExp.$4;
this.now=new Date(); this.nowFullYear=this.now.getFullYear()+""; this.nowCentury=this.nowFullYear.substring(0,2); this.nowShortYear=this.nowFullYear.substring(2,4);
Nu sker en koll om året du matat in är mindre än eller lika med värdet på "kortåret" han plockade ut via Date. Om det är det tilldelas det värdet som står till vänster om kolonet : om inte det till höger. Vänster värdet antar värdet för det sekel vi lever i (2000) plus de siffror som användaren matade in. Värdet till höger antar värdet för förra seklet (1900) och plussar på användarens år. Värdet skickas till this objektet och lagras i fullYear
Sker på denna rad:
this.fullYear=(this.year*1<=this.nowShortYear*1)?(this.nowCentury+this.year)*1:((this.nowCentury*1-1)+this.year)*1;
På nästa två rader skapar han en array med hur många dagar det finns i de olika månaderna samt gör en skottårskoll. Han tar this.fullYear och kollar om det är jämt delbara med 400. ELLER jämt delbart med 4 OCH 100, detta sker med modulus, ett tecken om ser ut som % om det är jämt delbart returnerar den noll, är det inte jämt delbart så får du en rest. Om det är jämt delbart så ändrar han värdet på months[1], där 1 är indexet för februari månad.
Så här ser det ut i JavaScript:
var months = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
if(this.fullYear%400==0||this.fullYear%4==0&&this.fullYear%100!=0){ months[1]=29; }
Nu kollar jojoxx av om man har fyllt i månaderna inom ett intervall av 1-12 samt att du inte angett för många dagar till den aktuella månaden som du är född i. Har du fyllt i fel returnerar funktionen false
if(this.month*1<1||this.month*1>12||this.day*1<1||this.day*1>months[this.month*1-1]){ return false; }
Efter detta plussar han ihop hela personnummret igen och gör om det till en checksumma. Han kollar sedan om den är jämt delbart med 10 återigen genom att använda modulus. Är den det så ändras this.valid till true.
var nn="";
for(var n=0;n<this.alldigits.length;n++){ nn+=((((n+1)%2)+1)*this.alldigits.substring(n,n+1)); }
this.checksum=0;
for(var n=0;n<nn.length;n++){ this.checksum+=nn.substring(n,n+1)*1; }
this.valid=(this.checksum%10==0)?true:false;
Objektet har ytterligare en egenskap. Nämligen this.sex, där du får ut kontrollsiffran för om personen som matade in personnummret är tjej eller kille.