diff --git a/src/shared/types/date/index.ts b/src/shared/types/date/index.ts new file mode 100644 index 0000000..ee257d2 --- /dev/null +++ b/src/shared/types/date/index.ts @@ -0,0 +1,5 @@ +export type YYYY = `${number}${number}${number}${number}`; +export type MM = `${number}${number}`; +export type DD = `${number}${number}`; + +export type DataDateString = `${DD}/${MM}/${YYYY}`; diff --git a/src/shared/utils/date/date.spec.ts b/src/shared/utils/date/date.spec.ts index fb49beb..39f0878 100644 --- a/src/shared/utils/date/date.spec.ts +++ b/src/shared/utils/date/date.spec.ts @@ -1,4 +1,9 @@ -import { firstDayOfMonthDate, lastDayOfMonthDate } from './date'; +import { + daysCountBetween, + firstDayOfMonthDate, + getDataDateString, + lastDayOfMonthDate, +} from './date'; describe('Check firstDayOfMonthDate func', () => { test('Check middle of month', () => { @@ -87,3 +92,99 @@ describe('Check lastDayOfMonthDate func', () => { expect(lastDayOfMonthDate(date)).toEqual(result); }); }); + +describe('Check getDataDateString func', () => { + test('Check middle of month', () => { + const date = new Date(2022, 7, 15); + const result = '08/15/2022'; + expect(getDataDateString(date)).toEqual(result); + }); + + test('Check end of year', () => { + const date = new Date(2024, 11, 31); + const result = '12/31/2024'; + expect(getDataDateString(date)).toEqual(result); + }); + + test('Check start of year', () => { + const date = new Date(2024, 0, 0); + const result = '12/31/2023'; + + expect(getDataDateString(date)).toEqual(result); + }); + + test('Check with 0 date', () => { + const date = new Date(2023, 12, 0); + const result = '12/31/2023'; + expect(getDataDateString(date)).toEqual(result); + }); + + test('Check with extra month', () => { + const date = new Date(2023, 12, 1); + const result = '01/01/2024'; + expect(getDataDateString(date)).toEqual(result); + }); + + test('Check with extra date', () => { + const date = new Date(2023, 11, 33); + const result = '01/02/2024'; + expect(getDataDateString(date)).toEqual(result); + }); + + test('Check with extra date and month', () => { + const date = new Date(2023, 12, 33); + const result = '02/02/2024'; + expect(getDataDateString(date)).toEqual(result); + }); +}); + +describe('Check daysCountBetween func', () => { + test('Check middle of month', () => { + const date1 = new Date(2022, 7, 15); + const date2 = new Date(2022, 7, 21); + const result = 6; + expect(daysCountBetween(date1, date2)).toEqual(result); + }); + + test('Check end of year', () => { + const date1 = new Date(2024, 11, 31); + const date2 = new Date(2024, 10, 30); + const result = 31; + expect(daysCountBetween(date1, date2)).toEqual(result); + }); + + test('Check start of year', () => { + const date1 = new Date(2024, 0, 0); + const date2 = new Date(2023, 11, 31); + const result = 0; + expect(daysCountBetween(date1, date2)).toEqual(result); + }); + + test('Check with 0 date', () => { + const date1 = new Date(2023, 12, 0); + const date2 = new Date(2023, 12, 21); + const result = 21; + expect(daysCountBetween(date1, date2)).toEqual(result); + }); + + test('Check with extra month', () => { + const date1 = new Date(2023, 12, 1); + const date2 = new Date(2022, 7, 21); + const result = 498; + expect(daysCountBetween(date1, date2)).toEqual(result); + }); + + test('Check with extra date', () => { + const date1 = new Date(2023, 11, 33); + const date2 = new Date(2022, 7, 21); + const result = 499; + expect(daysCountBetween(date1, date2)).toEqual(result); + }); + + test('Check with extra date and month', () => { + const date1 = new Date(2023, 12, 33); + const date2 = new Date(2022, 7, 21); + const result = 530; + expect(daysCountBetween(date1, date2)).toEqual(result); + }); +}); diff --git a/src/shared/utils/date/date.ts b/src/shared/utils/date/date.ts index 6bcb1c9..1d9c979 100644 --- a/src/shared/utils/date/date.ts +++ b/src/shared/utils/date/date.ts @@ -1,3 +1,5 @@ +import type { DataDateString } from 'shared/types/date'; + export const firstDayOfMonthDate = (date: Date) => { const monthIndex = date.getMonth(); const year = date.getFullYear(); @@ -11,3 +13,21 @@ export const lastDayOfMonthDate = (date: Date) => { return new Date(year, monthIndex + 1, 0); }; + +export const getDataDateString = (date: Date): DataDateString => { + const locale: Intl.LocalesArgument = 'en-En'; + const options: Intl.DateTimeFormatOptions = { + year: 'numeric', + month: '2-digit', + day: '2-digit', + }; + + return new Date(date).toLocaleDateString(locale, options) as DataDateString; +}; + +export const daysCountBetween = (date1: Date, date2: Date) => { + const ONE_DAY = 1000 * 60 * 60 * 24; + const differenceMs = Math.abs(date1.getTime() - date2.getTime()); + + return Math.round(differenceMs / ONE_DAY); +}; diff --git a/src/shared/utils/date/index.ts b/src/shared/utils/date/index.ts index 560d0e6..498ba93 100644 --- a/src/shared/utils/date/index.ts +++ b/src/shared/utils/date/index.ts @@ -1,4 +1,6 @@ export { lastDayOfMonthDate, firstDayOfMonthDate, + getDataDateString, + daysCountBetween, } from './date'; diff --git a/src/shared/utils/spec-helpers/date/index.ts b/src/shared/utils/spec-helpers/date/index.ts new file mode 100644 index 0000000..4953ffe --- /dev/null +++ b/src/shared/utils/spec-helpers/date/index.ts @@ -0,0 +1,18 @@ +// eslint-disable-next-line import/no-extraneous-dependencies +import { fireEvent } from '@testing-library/react'; + +import type { DataDateString } from 'shared/types/date'; + +// todo fix +// eslint-disable-next-line @stylistic/no-extra-parens +export const getDateCellByDataDate = (container: HTMLElement, dataDate: DataDateString) => ( + container.querySelector(`[data-date="${dataDate}"]`) +); + +export const pickCellByDataDate = (...params: Parameters) => { + const cellElem = getDateCellByDataDate(...params); + if (!cellElem) { + throw new Error('first cell not found'); + } + fireEvent.click(cellElem); +}; diff --git a/src/shared/utils/type/index.ts b/src/shared/utils/type/index.ts new file mode 100644 index 0000000..a11b59d --- /dev/null +++ b/src/shared/utils/type/index.ts @@ -0,0 +1,5 @@ +// @ts-expect-error +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export const exhaustiveCheck = (param: never): never => { + throw new Error('should not reach here'); +};