-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
43 lines (32 loc) · 1.06 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
const pattern = /^\d{6}(\d{2})?[+-]?\d{4}$/;
const hasCorrectChecksum = (input: string) => {
const sum = input
.split('')
.reverse()
.map(Number)
.map((x, i) => i % 2 ? x * 2 : x)
.map((x) => x > 9 ? x - 9 : x)
.reduce((x, y) => x + y);
return sum % 10 === 0;
};
const hasValidDate = (input: string) => {
let [_, yearStr, monthStr, dayStr] = /^(\d{2})(\d{2})(\d{2})/.exec(input);
const year = Number(yearStr);
const month = Number(monthStr) - 1;
let day = Number(dayStr);
if (day > 60) { // coordination numbers ("samordningsnummer")
day -= 60;
}
const date = new Date(year, month, day);
const yearIsValid = String(date.getFullYear()).substr(-2) === yearStr;
const monthIsValid = date.getMonth() === month;
const dayIsValid = date.getDate() === day;
return yearIsValid && monthIsValid && dayIsValid;
};
export const isValid = (input: string) => {
if (!pattern.test(input)) {
return false;
}
const cleaned = input.replace(/[+-]/, '').slice(-10);
return hasCorrectChecksum(cleaned) && hasValidDate(cleaned);
};