@@ -109,11 +109,14 @@ type PersonalIdentityNumberOptions = ValidatorOptions;
109109/**
110110 * Validates that the input value is a Norwegian national identity number.
111111 *
112- * Supports both fødselsnummer and d-number .
112+ * Supports both fødselsnummer and d-nummer .
113113 * @example
114114 * ```
115+ * // Fødselsnummer
115116 * validatePersonalIdentityNumber('21075417753') // => true
116- * validatePersonalIdentityNumber('61075440676') // => true
117+ *
118+ * // D-nummer
119+ * validatePersonalIdentityNumber('53097248016') // => true
117120 * ```
118121 */
119122export function validateNationalIdentityNumber (
@@ -125,30 +128,37 @@ export function validateNationalIdentityNumber(
125128 value = stripFormatting ( value ) ;
126129 }
127130
128- // Fødselsn
129- // Fødselsnummer and d numbers have two control digits.
130- // where the first one is calculated using the first 10 digits.
131+ // Norwegian national identity numbers use mod 11 with two control digits.
132+ // The first one is calculated for the first 10d digits
133+ // while the last one uses all 11 digits
131134 const valueForControlDigit1 = value . slice ( 0 , - 1 ) ;
132135 const controlDigit1 = mod11 (
133136 valueForControlDigit1 ,
134137 [ 3 , 7 , 6 , 1 , 8 , 9 , 4 , 5 , 2 ] ,
135138 ) ;
139+
136140 const controlDigit2 = mod11 ( value , [ 5 , 4 , 3 , 2 , 7 , 6 , 5 , 4 , 3 , 2 ] ) ;
137141
138- if ( ! controlDigit1 && ! controlDigit2 ) {
142+ if ( ! controlDigit1 || ! controlDigit2 ) {
139143 return false ;
140144 }
141145
142146 let day = Number ( value . substring ( 0 , 2 ) ) ;
143147 const month = Number ( value . substring ( 2 , 4 ) ) ;
144- const year = Number ( value . substring ( 4 , 6 ) ) ;
148+ let year = Number ( value . substring ( 4 , 6 ) ) ;
149+
150+ // 1900 isn't a leap year
151+ if ( year === 0 ) {
152+ year = 2000 ;
153+ }
145154
146155 // for a d-number the first digit is increased by 4. Eg the 31st of a month would be 71, or the 3rd would be 43.
147156 // thus we need to subtract 40 to get the correct day of the month
148157 if ( day >= 40 ) {
149158 day = day - 40 ;
150159 }
151160
161+ // important to use UTC so the user's timezone doesn't affect the validation
152162 const date = new Date ( Date . UTC ( year , month - 1 , day ) ) ;
153163
154164 return date && date . getUTCMonth ( ) === month - 1 && date . getUTCDate ( ) === day ;
0 commit comments