diff --git a/.changeset/spicy-teachers-admire.md b/.changeset/spicy-teachers-admire.md new file mode 100644 index 00000000..1060b6f8 --- /dev/null +++ b/.changeset/spicy-teachers-admire.md @@ -0,0 +1,5 @@ +--- +"es-hangul": minor +--- + +feat: 숫자를 날짜를 나타내는 순우리말로 바꿔주는 함수 중 days를 추가 diff --git a/docs/src/pages/docs/api/date.en.mdx b/docs/src/pages/docs/api/date.en.mdx new file mode 100644 index 00000000..db50201f --- /dev/null +++ b/docs/src/pages/docs/api/date.en.mdx @@ -0,0 +1,48 @@ +--- +title: date +--- + +import { Sandpack } from '@/components/Sandpack'; + +# date + +Convert numbers to native Korean words representing dates. The given number is valid when it is greater than 0 and less than or equal to 30. + +## days + +Convert numbers to native Korean words for days. + +```typescript +function days( + // Number to convert + num: number +): string; +``` + +### Examples + +```typescript +days(1); // '하루' +days(2); // '이틀' +days(3); // '사흘' +days(10); // '열흘' +days(11); // '열하루' +days(20); // '스무날' +days(29); // '스무아흐레' +days(30); // '서른날' +``` + +### Demo + +
+ + + +```ts index.ts +import { days } from 'es-hangul'; + +console.log(days(3)); +console.log(days(4)); +``` + + diff --git a/docs/src/pages/docs/api/date.ko.mdx b/docs/src/pages/docs/api/date.ko.mdx new file mode 100644 index 00000000..7073af87 --- /dev/null +++ b/docs/src/pages/docs/api/date.ko.mdx @@ -0,0 +1,48 @@ +--- +title: date +--- + +import { Sandpack } from '@/components/Sandpack'; + +# date + +숫자를 날짜를 나타내는 순우리말로 바꿔줍니다. 주어진 숫자가 0보다 크고 30 이하일 때 유효합니다. + +## days + +숫자를 순우리말 날로 바꿔줍니다. + +```typescript +function days( + // 변환할 숫자 + num: number +): string; +``` + +### Examples + +```typescript +days(1); // '하루' +days(2); // '이틀' +days(3); // '사흘' +days(10); // '열흘' +days(11); // '열하루' +days(20); // '스무날' +days(29); // '스무아흐레' +days(30); // '서른날' +``` + +### 사용해보기 + +
+ + + +```ts index.ts +import { days } from 'es-hangul'; + +console.log(days(3)); +console.log(days(4)); +``` + + diff --git a/src/date/date.spec.ts b/src/date/date.spec.ts new file mode 100644 index 00000000..9dc1ff85 --- /dev/null +++ b/src/date/date.spec.ts @@ -0,0 +1,36 @@ +import { days } from '.'; + +describe('date', () => { + describe('days', () => { + const validNumbers = [ + { num: 1, word: '하루' }, + { num: 2, word: '이틀' }, + { num: 3, word: '사흘' }, + { num: 4, word: '나흘' }, + { num: 5, word: '닷새' }, + { num: 6, word: '엿새' }, + { num: 7, word: '이레' }, + { num: 8, word: '여드레' }, + { num: 9, word: '아흐레' }, + { num: 10, word: '열흘' }, + { num: 11, word: '열하루' }, + { num: 20, word: '스무날' }, + { num: 21, word: '스무하루' }, + { num: 30, word: '서른날' }, + ]; + + const invalidNumbers = [0, -1, 31, 1.1, -1.1, Infinity, -Infinity, NaN]; + + validNumbers.forEach(({ num, word }) => { + it(`${num} - 순 우리말 날짜 ${word}로 바꿔 반환해야 한다.`, () => { + expect(days(num)).toBe(word); + }); + }); + + invalidNumbers.forEach(num => { + it(`유효하지 않은 숫자 ${num}에 대해 오류를 발생시켜야 한다.`, () => { + expect(() => days(num)).toThrow('지원하지 않는 숫자입니다.'); + }); + }); + }); +}); diff --git a/src/date/days.constants.ts b/src/date/days.constants.ts new file mode 100644 index 00000000..db5b082c --- /dev/null +++ b/src/date/days.constants.ts @@ -0,0 +1,19 @@ +export const DAYS_MAP = { + 1: '하루', + 2: '이틀', + 3: '사흘', + 4: '나흘', + 5: '닷새', + 6: '엿새', + 7: '이레', + 8: '여드레', + 9: '아흐레', + 10: '열', + 20: '스무', +} as const; + +export const DAYS_ONLY_TENS_MAP = { + 10: '열흘', + 20: '스무날', + 30: '서른날', +} as const; diff --git a/src/date/index.ts b/src/date/index.ts new file mode 100644 index 00000000..04912cfb --- /dev/null +++ b/src/date/index.ts @@ -0,0 +1,28 @@ +import { hasProperty } from '../_internal'; +import { DAYS_MAP, DAYS_ONLY_TENS_MAP } from './days.constants'; + +export function days(num: number): string { + return getNumberWord(num); +} + +function getNumberWord(num: number): string { + validateNumber(num); + + const tens = Math.floor(num / 10) * 10; + const ones = num % 10; + + if (ones === 0 && hasProperty(DAYS_ONLY_TENS_MAP, tens)) { + return DAYS_ONLY_TENS_MAP[tens]; + } + + const tensWord = hasProperty(DAYS_MAP, tens) ? DAYS_MAP[tens] : ''; + const onesWord = hasProperty(DAYS_MAP, ones) ? DAYS_MAP[ones] : ''; + + return `${tensWord}${onesWord}`; +} + +function validateNumber(num: number): void { + if (Number.isNaN(num) || num <= 0 || num > 30 || !Number.isInteger(num) || !Number.isFinite(num)) { + throw new Error('지원하지 않는 숫자입니다.'); + } +} diff --git a/src/index.ts b/src/index.ts index 44ab09b2..c1a6cd7a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,7 @@ export { assemble } from './assemble'; export { combineCharacter, combineVowels } from './combineCharacter'; export { convertQwertyToHangul, convertQwertyToAlphabet } from './convertQwertyToAlphabet'; +export { days } from './date'; export { disassemble, disassembleToGroups } from './disassemble'; export { disassembleCompleteCharacter } from './disassembleCompleteCharacter'; export { josa } from './josa';