IDCard::sex()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 2
eloc 2
nc 2
nop 0
crap 2
1
<?php
2
3
namespace Leonis\IDCard;
4
5
class IDCard
6
{
7
    /**
8
     * 身份证号.
9
     *
10
     * @var string
11
     */
12
    protected $id;
13
14
    /**
15
     * 行政区划代码
16
     *
17
     * @var array
18
     */
19
    protected $areaCodes;
20
21 16
    public function __construct(string $id)
22
    {
23 16
        $this->id = strtoupper($id);
24 16
        $this->areaCodes = (array) require __DIR__.'/../data/codes.php';
25 16
    }
26
27
    /**
28
     * 验证身份号.
29
     *
30
     * @return bool
31
     */
32 1
    public function check() : bool
33
    {
34 1
        return $this->checkBirthday() && $this->checkCode();
35
    }
36
37
    /**
38
     * 验证行政区划代码
39
     *
40
     * @return bool
41
     */
42 1
    public function checkAreaCode() : bool
43
    {
44 1
        $areaCode = substr($this->id, 0, 6);
45
46 1
        return array_key_exists($areaCode, $this->areaCodes);
47
    }
48
49
    /**
50
     * 验证生日.
51
     *
52
     * @return bool
53
     */
54 2
    public function checkBirthday() : bool
55
    {
56 2
        $year = substr($this->id, 6, 4);
57 2
        $month = substr($this->id, 10, 2);
58 2
        $day = substr($this->id, 12, 2);
59
60 2
        return checkdate($month, $day, $year);
61
    }
62
63
    /**
64
     * 验证校验码
65
     *
66
     * @return bool
67
     */
68 2
    public function checkCode() : bool
69
    {
70 2
        $weight = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
71 2
        $codes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
72 2
        $validate = substr($this->id, 0, 17);
73 2
        $sum = 0;
74 2
        for ($i = 0; $i < 17; $i++) {
75 2
            $sum += substr($validate, $i, 1) * $weight[$i];
76
        }
77
78 2
        return $codes[$sum % 11] == substr($this->id, 17, 1);
79
    }
80
81
    /**
82
     * 获取地址
83
     *
84
     * @param string $separator
85
     *
86
     * @return string
87
     */
88 1
    public function address(string $separator = '') : string
89
    {
90 1
        return $this->province().$separator.$this->city().$separator.$this->zone();
91
    }
92
93
    /**
94
     * 获取省
95
     *
96
     * @return string
97
     */
98 2
    public function province() : string
99
    {
100 2
        return $this->areaCodes[substr($this->id, 0, 2).'0000'];
101
    }
102
103
    /**
104
     * 获取市
105
     *
106
     * @return string
107
     */
108 2
    public function city() : string
109
    {
110 2
        return $this->areaCodes[substr($this->id, 0, 4).'00'];
111
    }
112
113
    /**
114
     * 获取区.
115
     *
116
     * @return string
117
     */
118 2
    public function zone() : string
119
    {
120 2
        return $this->areaCodes[substr($this->id, 0, 6)];
121
    }
122
123
    /**
124
     * 获取生日.
125
     *
126
     * @param string $format
127
     *
128
     * @return string
129
     */
130 1
    public function birthday(string $format = 'Y-m-d') : string
131
    {
132 1
        return date($format, strtotime($this->year().'-'.$this->month().'-'.$this->day()));
133
    }
134
135
    /**
136
     * 获取年.
137
     *
138
     * @return int
139
     */
140 4
    public function year() : int
141
    {
142 4
        return (int) substr($this->id, 6, 4);
143
    }
144
145
    /**
146
     * 获取月.
147
     *
148
     * @return int
149
     */
150 4
    public function month() : int
151
    {
152 4
        return (int) substr($this->id, 10, 2);
153
    }
154
155
    /**
156
     * 获取日.
157
     *
158
     * @return int
159
     */
160 4
    public function day() : int
161
    {
162 4
        return (int) substr($this->id, 12, 2);
163
    }
164
165
    /**
166
     * 获取年龄.
167
     *
168
     * @return int
169
     */
170 1
    public function age() : int
171
    {
172 1
        $year = $this->year();
173 1
        $month = $this->month();
174 1
        $day = $this->day();
175
176 1
        $nowYear = (int) date('Y');
177 1
        $nowMonth = (int) date('n');
178 1
        $nowDay = (int) date('j');
179
180 1
        $age = $nowYear > $year ? $nowYear - $year - 1 : 0;
181 1
        if ($nowMonth > $month || ($nowMonth === $month && $nowDay >= $day)) {
182 1
            $age++;
183
        }
184
185 1
        return $age;
186
    }
187
188
    /**
189
     * 获取性别.
190
     *
191
     * @return string
192
     */
193 1
    public function sex() : string
194
    {
195 1
        return substr($this->id, 16, 1) % 2 ? '男' : '女';
196
    }
197
198
    /**
199
     * 获取星座.
200
     *
201
     * @return string
202
     */
203 1
    public function constellation() : string
204
    {
205 1
        $constellation = ['水瓶座', '双鱼座', '白羊座', '金牛座', '双子座', '巨蟹座', '狮子座', '处女座', '天秤座', '天蝎座', '射手座', '魔羯座'];
206 1
        $constellationDays = [21, 20, 21, 20, 21, 22, 23, 23, 23, 24, 22, 21];
207
208 1
        $month = $this->month() - 1;
209 1
        $day = $this->day();
210
211 1
        if ($day < $constellationDays[$month]) {
212 1
            $month--;
213
        }
214
215 1
        return $month >= 0 ? $constellation[$month] : $constellation[11];
216
    }
217
218
    /**
219
     * 获取属相.
220
     *
221
     * @return string
222
     */
223 1
    public function zodiac() : string
224
    {
225 1
        $zodiac = ['牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪', '鼠'];
226 1
        $index = abs($this->year() - 1901) % 12;
227
228 1
        return $zodiac[$index];
229
    }
230
}
231