-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(utils): getAge, isUnderAge 신규 함수 추가 (#662)
* feat(utils): getAge 신규 함수 추가 * feat(utils): isUnderAge 신규 함수 추가
- Loading branch information
Showing
9 changed files
with
291 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@modern-kit/utils': minor | ||
--- | ||
|
||
feat(utils): getAge 신규 함수 추가 - @ssi02014 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@modern-kit/utils': minor | ||
--- | ||
|
||
feat(utils): isUnderAge 신규 함수 추가 - @ssi02014 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# getAge | ||
|
||
주어진 `생년월일`을 기준으로 `현재 나이`를 계산합니다. | ||
|
||
<br /> | ||
|
||
## Code | ||
[🔗 실제 구현 코드 확인](https://github.com/modern-agile-team/modern-kit/blob/main/packages/utils/src/validator/getAge/index.ts) | ||
|
||
## Interface | ||
```ts title="typescript" | ||
function getAge(birthDate: string | number | Date): number | ||
``` | ||
|
||
## Usage | ||
|
||
```ts title="typescript" | ||
import { getAge } from '@modern-kit/utils'; | ||
// 현재 날짜가 2025년 1월 1일 00:00:00 일 때 | ||
getAge(new Date('2006-01-01')); // 19 | ||
// 문자열 포맷도 허용합니다. | ||
getAge('2006-01-01'); // 19 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# isUnderAge | ||
|
||
주어진 생년월일을 기준으로 특정 나이보다 어린지 확인합니다. | ||
|
||
`inclusive` 값을 기준으로 기준 나이를 포함할지 여부를 결정합니다. | ||
|
||
<br /> | ||
|
||
## Code | ||
[🔗 실제 구현 코드 확인](https://github.com/modern-agile-team/modern-kit/blob/main/packages/utils/src/validator/isUnderAge/index.ts) | ||
|
||
## Interface | ||
```ts title="typescript" | ||
interface IsUnderAgeParams { | ||
birthDate: string | number | Date; | ||
targetAge: number; | ||
inclusive?: boolean; | ||
} | ||
``` | ||
```ts title="typescript" | ||
function isUnderAge({ | ||
birthDate, | ||
targetAge, | ||
inclusive = false, | ||
}: IsUnderAgeParams): boolean; | ||
``` | ||
|
||
## Usage | ||
### without inclusive | ||
```ts title="typescript" | ||
import { isUnderAge } from '@modern-kit/utils'; | ||
|
||
// 현재 날짜 2025년 1월 1일 기준 | ||
isUnderAge({ birthDate: new Date('2006-01-02'), targetAge: 19 }); // true | ||
isUnderAge({ birthDate: new Date('2006-01-01'), targetAge: 19 }); // false, 정확히 만 19세 | ||
isUnderAge({ birthDate: new Date('2005-12-31'), targetAge: 19 }); // false | ||
|
||
isUnderAge({ birthDate: '2006-01-02', targetAge: 19 }); // true | ||
isUnderAge({ birthDate: '2006-01-01', targetAge: 19 }); // false, 정확히 만 19세 | ||
isUnderAge({ birthDate: '2005-12-31', targetAge: 19 }); // false | ||
``` | ||
|
||
### with inclusive | ||
- `inclusive` 값을 기준으로 기준 나이를 포함할지 여부를 결정합니다. (기본값: `false`) | ||
- `inclusive` 값이 `true`일 경우, 기준 나이를 포함하며, `false`일 경우, 기준 나이를 포함하지 않습니다. | ||
|
||
```ts title="typescript" | ||
// 2025년 01월 01일 기준 | ||
// inclusive 값을 기준으로 기준 나이를 포함할지 여부를 결정합니다. | ||
isUnderAge({ birthDate: '2006-01-01', targetAge: 19, inclusive: true }); // true | ||
isUnderAge({ birthDate: '2006-01-01', targetAge: 19, inclusive: false }); // false | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { describe, expect, it, beforeEach, vi, afterEach } from 'vitest'; | ||
import { getAge } from '.'; | ||
|
||
beforeEach(() => { | ||
/** | ||
* 테스트를 위해 2025년 01월 01일로 날짜 고정 | ||
* | ||
* 1. 2005년 01월 01일: 만 20세 | ||
* 2. 2006년 01월 01일: 정확히 만 19세 (기대값: false) | ||
* 3. 2007년 01월 01일: 만 18세 | ||
*/ | ||
vi.setSystemTime(new Date('2025-01-01')); | ||
}); | ||
|
||
afterEach(() => { | ||
vi.useRealTimers(); | ||
}); | ||
|
||
describe('getAge', () => { | ||
it('Date 객체로 나이를 정확히 계산해야 함', () => { | ||
expect(getAge(new Date('2007-01-01'))).toBe(18); | ||
|
||
expect(getAge(new Date('2006-06-01'))).toBe(18); // 생일이 지나지 않은 경우 | ||
expect(getAge(new Date('2006-01-01'))).toBe(19); | ||
expect(getAge(new Date('2005-12-31'))).toBe(19); // 생일이 지난 경우 | ||
|
||
expect(getAge(new Date('2005-01-01'))).toBe(20); | ||
}); | ||
|
||
it('날짜 문자열로 나이를 정확히 계산해야 함', () => { | ||
expect(getAge('2007-01-01')).toBe(18); | ||
|
||
expect(getAge('2006-06-01')).toBe(18); // 생일이 지나지 않은 경우 | ||
expect(getAge('2006-01-01')).toBe(19); | ||
expect(getAge('2005-12-31')).toBe(19); // 생일이 지난 경우 | ||
|
||
expect(getAge('2005-01-01')).toBe(20); | ||
}); | ||
|
||
it('잘못된 날짜 형식에 대해 에러를 발생시켜야 함', () => { | ||
expect(() => getAge('invalid-date')).toThrow( | ||
'유효하지 않은 날짜 형식입니다.' | ||
); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/** | ||
* @description 주어진 생년월일을 기준으로 현재 나이를 계산합니다. | ||
* | ||
* @param {string | number | Date} birthDate - 확인하고자 하는 생년월일 | ||
* @returns {number} 현재 나이 (만 나이) | ||
* | ||
* @example | ||
* // 현재 날짜 2025년 01월 01일 기준 | ||
* getAge(new Date('2006-01-01')); // 19 | ||
* | ||
* @example | ||
* // 2025년 01월 01일 기준 | ||
* getAge('2006-01-01'); // 19 | ||
* | ||
*/ | ||
export function getAge(birthDate: string | number | Date): number { | ||
const birthDateTime = new Date(birthDate); | ||
|
||
if (isNaN(birthDateTime.getTime())) { | ||
throw new Error('유효하지 않은 날짜 형식입니다.'); | ||
} | ||
|
||
const today = new Date(); | ||
|
||
const age = today.getFullYear() - birthDateTime.getFullYear(); | ||
const monthDiff = today.getMonth() - birthDateTime.getMonth(); | ||
const dayDiff = today.getDate() - birthDateTime.getDate(); | ||
|
||
// 만약, 생일이 지나지 않았다면 나이에서 1을 뺀다. | ||
if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) { | ||
return age - 1; | ||
} | ||
|
||
return age; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,6 @@ | ||
export * from './getAge'; | ||
export * from './getDDay'; | ||
export * from './isAfterDate'; | ||
export * from './isBeforeDate'; | ||
export * from './isDateInRange'; | ||
export * from './isUnderAge'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { getAge } from '../getAge'; | ||
|
||
interface IsUnderAgeParams { | ||
birthDate: string | number | Date; | ||
targetAge: number; | ||
inclusive?: boolean; | ||
} | ||
|
||
/** | ||
* @description 주어진 생년월일을 기준으로 특정 나이보다 어린지 확인합니다. | ||
* | ||
* `inclusive` 값을 기준으로 기준 나이를 포함할지 여부를 결정합니다. | ||
* | ||
* @param {IsUnderAgeParams} params - 확인하고자 하는 생년월일 | ||
* @param {string | number| Date} params.birthDate - 확인하고자 하는 생년월일 | ||
* @param {number} params.targetAge - 비교할 기준 나이 | ||
* @param {boolean} params.inclusive - 기준 나이에 포함 여부 | ||
* @returns {boolean} 대상이 기준 나이보다 어리면 true, 아니면 false | ||
* @throws {Error} 유효하지 않은 날짜 형식이 입력된 경우 | ||
* | ||
* @example | ||
* // 2025년 01월 01일 기준 | ||
* isUnderAge({ birthDate: new Date('2006-01-02'), targetAge: 19 }); // true | ||
* isUnderAge({ birthDate: new Date('2006-01-01'), targetAge: 19 }); // false, 정확히 만 19세 | ||
* isUnderAge({ birthDate: new Date('2005-12-31'), targetAge: 19 }); // false | ||
* | ||
* isUnderAge({ birthDate: '2006-01-02', targetAge: 19 }); // true | ||
* isUnderAge({ birthDate: '2006-01-01', targetAge: 19 }); // false, 정확히 만 19세 | ||
* isUnderAge({ birthDate: '2005-12-31', targetAge: 19 }); // false | ||
* | ||
* @example | ||
* // 2025년 01월 01일 기준 | ||
* // inclusive 값을 기준으로 기준 나이를 포함할지 여부를 결정합니다. | ||
* isUnderAge({ | ||
* birthDate: '2006-01-01', | ||
* targetAge: 19, | ||
* inclusive: true | ||
* }); // true | ||
*/ | ||
export function isUnderAge({ | ||
birthDate, | ||
targetAge, | ||
inclusive = false, | ||
}: IsUnderAgeParams): boolean { | ||
const age = getAge(birthDate); | ||
|
||
return inclusive ? age <= targetAge : age < targetAge; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; | ||
import { isUnderAge } from '.'; | ||
|
||
beforeEach(() => { | ||
/** | ||
* 테스트를 위해 2025년 01월 01일로 날짜 고정 | ||
* | ||
* 1. 2006년 01월 01일: 정확히 만 19세 (기대값: false) | ||
* 2. 2006년 01월 02일: 만 19세보다 어림 (기대값: true) | ||
* 3. 2005년 12월 31일: 만 19세보다 많음 (기대값: false) | ||
*/ | ||
vi.setSystemTime(new Date('2025-01-01')); | ||
}); | ||
|
||
afterEach(() => { | ||
vi.useRealTimers(); | ||
}); | ||
|
||
describe('isUnderAge', () => { | ||
it('만 19세 미만인 경우 true를 반환해야 합니다.', () => { | ||
// Date 객체 | ||
expect( | ||
isUnderAge({ birthDate: new Date('2006-01-02'), targetAge: 19 }) | ||
).toBeTruthy(); | ||
|
||
// 문자열 | ||
expect(isUnderAge({ birthDate: '2006-01-02', targetAge: 19 })).toBeTruthy(); | ||
}); | ||
|
||
it('정확히 만 19세인 경우 false를 반환해야 합니다.', () => { | ||
// Date 객체 | ||
expect( | ||
isUnderAge({ birthDate: new Date('2006-01-01'), targetAge: 19 }) | ||
).toBeFalsy(); | ||
|
||
// 문자열 | ||
expect(isUnderAge({ birthDate: '2006-01-01', targetAge: 19 })).toBeFalsy(); | ||
}); | ||
|
||
it('만 19세가 지난 경우 false를 반환해야 합니다.', () => { | ||
// Date 객체 | ||
expect( | ||
isUnderAge({ birthDate: new Date('2005-12-31'), targetAge: 19 }) | ||
).toBeFalsy(); | ||
|
||
// 문자열 | ||
expect(isUnderAge({ birthDate: '2005-12-31', targetAge: 19 })).toBeFalsy(); | ||
}); | ||
|
||
it('inclusive 값을 기준으로 기준 나이를 포함할지 여부를 결정해야 한다.', () => { | ||
// Date 객체 | ||
expect( | ||
isUnderAge({ | ||
birthDate: new Date('2006-01-01'), | ||
targetAge: 19, | ||
inclusive: true, | ||
}) | ||
).toBeTruthy(); | ||
|
||
// 문자열 | ||
expect( | ||
isUnderAge({ birthDate: '2006-01-01', targetAge: 19, inclusive: false }) | ||
).toBeFalsy(); | ||
}); | ||
|
||
it('잘못된 날짜 형식에 대해 에러를 던진다', () => { | ||
expect(() => | ||
isUnderAge({ birthDate: 'invalid-date', targetAge: 19 }) | ||
).toThrow('유효하지 않은 날짜 형식입니다.'); | ||
}); | ||
}); |