Skip to content

Commit 78a8e39

Browse files
authored
Merge pull request #4 from WongYC-66/refactor
Refactor: mykadDOB
2 parents f207e07 + 8b8c686 commit 78a8e39

File tree

5 files changed

+640
-50
lines changed

5 files changed

+640
-50
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

index.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Node.js v18+
2+
// usage : npx tsx --test index.test.ts
3+
import test from 'node:test';
4+
import assert from 'node:assert/strict';
5+
6+
import { mykadDOB } from "./index.ts";
7+
8+
test('mykadDOB return correct DOB', () => {
9+
assert.equal(mykadDOB("901030-55-1011"), '1990-10-30');
10+
assert.equal(mykadDOB("011030-55-1011"), '2001-10-30');
11+
});
12+
13+
test('mykadDOB reject INVALID month and day', () => {
14+
assert.equal(mykadDOB("900015-55-1011"), 'MYKAD INVALID');
15+
assert.equal(mykadDOB("901315-55-1011"), 'MYKAD INVALID');
16+
17+
assert.equal(mykadDOB("900132-55-1011"), 'MYKAD INVALID');
18+
assert.equal(mykadDOB("900230-55-1011"), 'MYKAD INVALID');
19+
assert.equal(mykadDOB("900332-55-1011"), 'MYKAD INVALID');
20+
assert.equal(mykadDOB("900431-55-1011"), 'MYKAD INVALID');
21+
assert.equal(mykadDOB("900532-55-1011"), 'MYKAD INVALID');
22+
assert.equal(mykadDOB("900631-55-1011"), 'MYKAD INVALID');
23+
assert.equal(mykadDOB("900732-55-1011"), 'MYKAD INVALID');
24+
assert.equal(mykadDOB("900832-55-1011"), 'MYKAD INVALID');
25+
assert.equal(mykadDOB("900931-55-1011"), 'MYKAD INVALID');
26+
assert.equal(mykadDOB("901032-55-1011"), 'MYKAD INVALID');
27+
assert.equal(mykadDOB("901131-55-1011"), 'MYKAD INVALID');
28+
assert.equal(mykadDOB("901232-55-1011"), 'MYKAD INVALID');
29+
});
30+

index.ts

Lines changed: 40 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -102,63 +102,55 @@ export function mykadDOB(mykad: string): string {
102102
if (!mykadValidator(mykad)) {
103103
return 'MYKAD INVALID';
104104
}
105-
const year = parseInt(mykad.substring(0, 2));
106-
const month =
107-
parseInt(mykad.substring(2, 4)) && parseInt(mykad.substring(2, 4)) < 10
108-
? '0' + parseInt(mykad.substring(2, 4))
109-
: parseInt(mykad.substring(2, 4));
110-
//if month is more than 12, it is invalid
111-
if (parseInt(mykad.substring(2, 4)) > 12) {
112-
return 'MYKAD INVALID';
113-
}
114-
const day =
115-
parseInt(mykad.substring(4, 6)) && parseInt(mykad.substring(4, 6)) < 10
116-
? '0' + parseInt(mykad.substring(4, 6))
117-
: parseInt(mykad.substring(4, 6));
118-
//if day is more than 31, it is invalid
119-
if (parseInt(mykad.substring(4, 6)) > 31) {
120-
return 'MYKAD INVALID';
105+
106+
function getYear(mykad: string) {
107+
return parseInt(mykad.substring(0, 2));
121108
}
122-
//if month is 2 and day is more than 29, it is invalid
123-
if (
124-
parseInt(mykad.substring(2, 4)) === 2 &&
125-
parseInt(mykad.substring(4, 6)) > 29
126-
) {
127-
return 'MYKAD INVALID';
109+
110+
function getMonth(mykad: string): string {
111+
return mykad.substring(2, 4).padStart(2, '0');
128112
}
129113

130-
//if month is january, march, may, july, august, october, december and day is more than 31, it is invalid
131-
if (
132-
(parseInt(mykad.substring(2, 4)) === 1 ||
133-
parseInt(mykad.substring(2, 4)) === 3 ||
134-
parseInt(mykad.substring(2, 4)) === 5 ||
135-
parseInt(mykad.substring(2, 4)) === 7 ||
136-
parseInt(mykad.substring(2, 4)) === 8 ||
137-
parseInt(mykad.substring(2, 4)) === 10 ||
138-
parseInt(mykad.substring(2, 4)) === 12) &&
139-
parseInt(mykad.substring(4, 6)) > 31
140-
) {
141-
return 'MYKAD INVALID';
114+
function getDay(mykad: string): string {
115+
return mykad.substring(4, 6).padStart(2, "0");
142116
}
143117

144-
//if month is april, june, september, november and day is more than 30, it is invalid
145-
if (
146-
(parseInt(mykad.substring(2, 4)) === 4 ||
147-
parseInt(mykad.substring(2, 4)) === 6 ||
148-
parseInt(mykad.substring(2, 4)) === 9 ||
149-
parseInt(mykad.substring(2, 4)) === 11) &&
150-
parseInt(mykad.substring(4, 6)) > 30
151-
) {
152-
return 'MYKAD INVALID';
118+
function isValidDayAndMonth(month: string, day: string): boolean {
119+
const MaxDayOfMonth = {
120+
'01': 31,
121+
'02': 29,
122+
'03': 31,
123+
'04': 30,
124+
'05': 31,
125+
'06': 30,
126+
'07': 31,
127+
'08': 31,
128+
'09': 30,
129+
'10': 31,
130+
'11': 30,
131+
'12': 31
132+
}
133+
134+
const isValidDay = (1 <= parseInt(day) && parseInt(day) <= 31)
135+
const isValidMonth = (1 <= parseInt(month) && parseInt(month) <= 12)
136+
const isDayCorrectInMonth = day <= MaxDayOfMonth[month];
137+
// Actually, lack of LeapYear check
138+
// e.g. 2025-02-29 INVALID
139+
return [isValidDay, isValidMonth, isDayCorrectInMonth].every(condition => condition === true);
153140
}
154141

142+
const year = getYear(mykad) // e.g. 84
143+
const month = getMonth(mykad) // e.g '08'
144+
const day = getDay(mykad) // e.g. 30'
145+
146+
// invalid
147+
if (!isValidDayAndMonth(month, day)) return "MYKAD INVALID";
148+
149+
// valid day & month
155150
const currentYear = new Date().getFullYear() % 100;
151+
const adjustedYear = year > currentYear ? year + 1900 : year + 2000; // assume everyone < 100 years old
156152

157-
if (year > currentYear) {
158-
return `19${year}-${month}-${day}`;
159-
} else {
160-
return `20${year}-${month}-${day}`;
161-
}
153+
return `${adjustedYear}-${month}-${day}`;
162154
}
163155

164156
/**

0 commit comments

Comments
 (0)