@@ -91,64 +91,57 @@ class Person extends \Faker\Provider\Person
91
91
*
92
92
* @see http://www.finlex.fi/fi/laki/ajantasa/2010/20100128
93
93
*
94
- * @param string $gender Person::GENDER_MALE || Person::GENDER_FEMALE
94
+ * @param static::GENDER_FEMALE|static::GENDER_MALE|null $gender
95
95
*
96
- * @return string on format DDMMYYCZZZQ, where DDMMYY is the date of birth, C the century sign, ZZZ the individual number and Q the control character (checksum)
96
+ * @return string on format DDMMYYCZZZQ, where DDMMYY is the date of birth,
97
+ * C the century sign, ZZZ the individual number and Q the
98
+ * control character (checksum)
97
99
*/
98
- public function personalIdentityNumber (\DateTime $ birthdate = null , $ gender = null )
99
- {
100
- $ checksumCharacters = '0123456789ABCDEFHJKLMNPRSTUVWXY ' ;
100
+ public function personalIdentityNumber (
101
+ ?\DateTime $ birthdate = null ,
102
+ ?string $ gender = null
103
+ ) {
104
+ $ birthdate ??= \Faker \Provider \DateTime::dateTimeThisCentury ();
105
+ $ centurySign = match ((int ) ($ birthdate ->format ('Y ' ) / 100 )) {
106
+ 18 => '+ ' ,
107
+ 19 => '- ' , // Technically can also be Y, X, W, V, or U
108
+ 20 => 'A ' , // Technically can also be B, C, D, E, or F
109
+ default => throw new \InvalidArgumentException (
110
+ 'Year must be between 1800 and 2099 inclusive. ' ,
111
+ ),
112
+ };
101
113
102
- if (!$ birthdate ) {
103
- $ birthdate = \Faker \Provider \DateTime::dateTimeThisCentury ();
104
- }
114
+ $ checksumCharacters = '0123456789ABCDEFHJKLMNPRSTUVWXY ' ;
105
115
$ datePart = $ birthdate ->format ('dmy ' );
116
+ $ randomDigits = $ this ->getBirthNumber ($ gender );
117
+ $ checksum = $ checksumCharacters [
118
+ (int ) ($ datePart . $ randomDigits ) % strlen ($ checksumCharacters )
119
+ ];
106
120
107
- switch ((int ) ($ birthdate ->format ('Y ' ) / 100 )) {
108
- case 18 :
109
- $ centurySign = '+ ' ;
110
-
111
- break ;
112
-
113
- case 19 :
114
- $ centurySign = '- ' ;
115
-
116
- break ;
117
-
118
- case 20 :
119
- $ centurySign = 'A ' ;
120
-
121
- break ;
122
-
123
- default :
124
- throw new \InvalidArgumentException ('Year must be between 1800 and 2099 inclusive. ' );
125
- }
126
-
127
- $ randomDigits = self ::numberBetween (0 , 89 );
121
+ return $ datePart . $ centurySign . $ randomDigits . $ checksum ;
122
+ }
128
123
129
- if ($ gender && $ gender == static ::GENDER_MALE ) {
130
- if ($ randomDigits === 0 ) {
131
- $ randomDigits .= static ::randomElement ([3 , 5 , 7 , 9 ]);
132
- } else {
133
- $ randomDigits .= static ::randomElement ([1 , 3 , 5 , 7 , 9 ]);
134
- }
135
- } elseif ($ gender && $ gender == static ::GENDER_FEMALE ) {
136
- if ($ randomDigits === 0 ) {
137
- $ randomDigits .= static ::randomElement ([2 , 4 , 6 , 8 ]);
138
- } else {
139
- $ randomDigits .= static ::randomElement ([0 , 2 , 4 , 6 , 8 ]);
140
- }
141
- } else {
142
- if ($ randomDigits === 0 ) {
143
- $ randomDigits .= self ::numberBetween (2 , 9 );
144
- } else {
145
- $ randomDigits .= (string ) static ::numerify ('# ' );
146
- }
147
- }
148
- $ randomDigits = str_pad ($ randomDigits , 3 , '0 ' , STR_PAD_LEFT );
124
+ /**
125
+ * Generate the birth number for person.
126
+ *
127
+ * Birth number is odd for men and even for women.
128
+ * Numbers 900-999 are reserved for temporary use.
129
+ * Number 001 is not used.
130
+ *
131
+ * @param static::GENDER_FEMALE|static::GENDER_MALE|null $gender
132
+ *
133
+ * @return numeric-string Gendered three digit birth number
134
+ */
135
+ protected function getBirthNumber (?string $ gender = null ): string
136
+ {
137
+ [$ min , $ max ] = match ($ gender ) {
138
+ static ::GENDER_MALE => [3 , 899 ],
139
+ static ::GENDER_FEMALE => [2 , 898 ],
140
+ default => [2 , 999 ],
141
+ };
149
142
150
- $ checksum = $ checksumCharacters [( int ) ($ datePart . $ randomDigits ) % strlen ( $ checksumCharacters )] ;
143
+ $ number = ( string ) ( mt_rand ( 0 , ( int ) (( $ max - $ min ) / 2 )) * 2 + $ min ) ;
151
144
152
- return $ datePart . $ centurySign . $ randomDigits . $ checksum ;
145
+ return str_pad ( $ number , 3 , ' 0 ' , STR_PAD_LEFT ) ;
153
146
}
154
147
}
0 commit comments