Skip to content

Commit 09eec33

Browse files
feat: Implemented interim numbers.
Signed-off-by: Johannes Tegnér <[email protected]>
1 parent 0865ef2 commit 09eec33

File tree

3 files changed

+28
-8
lines changed

3 files changed

+28
-8
lines changed

src/main/java/dev/personnummer/Personnummer.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@
1414
*/
1515
public final class Personnummer implements Comparable<Personnummer> {
1616
private static final Pattern regexPattern;
17+
private static final Pattern interimPatternTest;
18+
private static final String interimTestStr = "(?![-+])\\D";
1719

1820
static {
19-
regexPattern = Pattern.compile("^(\\d{2})?(\\d{2})(\\d{2})(\\d{2})([-+]?)?((?!000)\\d{3})(\\d?)$");
21+
regexPattern = Pattern.compile("^(\\d{2})?(\\d{2})(\\d{2})(\\d{2})([-+]?)?((?!000)\\d{3}|[TRSUWXJKLMN]\\d{2})(\\d?)$");
22+
interimPatternTest = Pattern.compile(interimTestStr);
2023
}
2124

2225
/**
@@ -112,6 +115,13 @@ public Personnummer(String personnummer, Options options) throws PersonnummerExc
112115
throw new PersonnummerException("Failed to parse personal identity number. Invalid input.");
113116
}
114117

118+
if (!options.allowInterimNumbers && interimPatternTest.matcher(personnummer).find()) {
119+
throw new PersonnummerException(
120+
personnummer +
121+
" contains non-integer characters and options are set to not allow interim numbers"
122+
);
123+
}
124+
115125
Matcher matches = regexPattern.matcher(personnummer);
116126
if (!matches.find()) {
117127
throw new PersonnummerException("Failed to parse personal identity number. Invalid input.");
@@ -154,9 +164,14 @@ public Personnummer(String personnummer, Options options) throws PersonnummerExc
154164

155165
this.isMale = Integer.parseInt(Character.toString(this.numbers.charAt(2))) % 2 == 1;
156166

167+
String nums = matches.group(6);
168+
if (options.allowInterimNumbers) {
169+
nums = nums.replaceFirst(interimTestStr, "1");
170+
}
171+
157172
// The format passed to Luhn method is supposed to be YYmmDDNNN
158173
// Hence all numbers that are less than 10 (or in last case 100) will have leading 0's added.
159-
if (luhn(String.format("%s%s%s%s", this.year, this.month, this.day, matches.group(6))) != Integer.parseInt(this.controlNumber)) {
174+
if (luhn(String.format("%s%s%s%s", this.year, this.month, this.day, nums)) != Integer.parseInt(this.controlNumber)) {
160175
throw new PersonnummerException("Invalid personal identity number.");
161176
}
162177
}

src/test/java/DataProvider.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,16 @@ public static void initialize() throws IOException {
7171
JSONObject current = rootObject.getJSONObject(i);
7272
interimNr.add(new PersonnummerData(
7373
current.getLong("integer"),
74+
current.getString("long_format"),
7475
current.getString("short_format"),
7576
current.getString("separated_format"),
77+
current.getString("separated_long"),
7678
current.getBoolean("valid"),
77-
current.getString("type")
78-
));
79+
current.getString("type"),
80+
false, // ignore
81+
false // ignore
82+
)
83+
);
7984
}
8085
}
8186

src/test/java/InterimnummerTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,17 @@ public void testValidateInvalidInterim(PersonnummerData ssn) {
3434
public void testFormatLongInterim(PersonnummerData ssn) throws PersonnummerException {
3535
Personnummer pnr = Personnummer.parse(ssn.longFormat, opts);
3636

37-
assertEquals(pnr.format(false), ssn.longFormat);
38-
assertEquals(pnr.format(), ssn.separatedFormat);
37+
assertEquals(pnr.format(false), ssn.separatedFormat);
38+
assertEquals(pnr.format(true), ssn.longFormat);
3939
}
4040

4141
@ParameterizedTest
4242
@MethodSource("DataProvider#getValidInterimNumbers")
4343
public void testFormatShortInterim(PersonnummerData ssn) throws PersonnummerException {
4444
Personnummer pnr = Personnummer.parse(ssn.shortFormat, opts);
4545

46-
assertEquals(pnr.format(false), ssn.longFormat);
47-
assertEquals(pnr.format(), ssn.separatedFormat);
46+
assertEquals(pnr.format(false), ssn.separatedFormat);
47+
assertEquals(pnr.format(true), ssn.longFormat);
4848
}
4949

5050
@ParameterizedTest

0 commit comments

Comments
 (0)