@@ -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