Skip to content

Commit

Permalink
Merge pull request #97 from Kyutech-C3/feat/DateDiffLabel-ui-#83
Browse files Browse the repository at this point in the history
feat: date diff label ui
  • Loading branch information
yamato0211 authored Nov 16, 2023
2 parents 35ba7f2 + b2bcfd0 commit ebeb2fa
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/components/ui/DateDiffLabel/constant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export const DATE_DIFF_LABEL = {
second: '秒前',
minute: '分前',
hour: '時間前',
day: '日前',
week: '週間前',
month: 'ヶ月前',
} as const;

export const MINUTE = 60;

export const HOUR = 60 * MINUTE;

export const DAY = 24 * HOUR;

export const WEEK = 7 * DAY;

export const MONTH = 30 * DAY;

export const YEAR = 365 * DAY;
63 changes: 63 additions & 0 deletions src/components/ui/DateDiffLabel/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { DateDiffLabel } from '.';

import type { Meta, StoryObj } from '@storybook/react';

const meta: Meta<typeof DateDiffLabel> = {
component: DateDiffLabel,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
};

export default meta;

type Story = StoryObj<typeof DateDiffLabel>;

export const Default: Story = {
args: { date: new Date() },
};

export const SecAgo: Story = {
args: { date: new Date(Date.now() - 1000) },
};

export const MinAgo: Story = {
args: { date: new Date(Date.now() - 1000 * 60) },
};

export const HourAgo: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60) },
};

export const DayAgo: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60 * 24) },
};

export const WeekAgo: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 7) },
};

export const MonthAgo: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 30) },
};

export const TwoMonthAgo: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 30 * 2) },
}

export const ThreeMonthAgo: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 30 * 3) },
}

export const SixMonthAgo: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 30 * 6) },
}

export const YearAgo: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 365) },
};

export const TwoYearAgo: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 365 * 2) },
};
48 changes: 48 additions & 0 deletions src/components/ui/DateDiffLabel/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { render, screen } from "@testing-library/react";

import "@testing-library/jest-dom";
import { DateDiffLabel } from ".";

describe('test ui/DateDiffLabel', () => {
const now = new Date(2023, 5, 15);
it('should display seconds when difference is less than a minute', () => {
render(<DateDiffLabel date={new Date(2023, 5, 14, 23, 59, 30)} now={now} />);
expect(screen.getByText(//)).toBeInTheDocument();
});

it('should display minutes when difference is less than an hour', () => {
render(<DateDiffLabel date={new Date(2023, 5, 14, 23, 30)} now={now} />);
expect(screen.getByText(//)).toBeInTheDocument();
});

it('should display hours when difference is less than a day', () => {
render(<DateDiffLabel date={new Date(2023, 5, 14, 23, 0)} now={now} />);
expect(screen.getByText(//)).toBeInTheDocument();
});

it('should display days when difference is less than a week', () => {
render(<DateDiffLabel date={new Date(2023, 5, 14)} now={now} />);
expect(screen.getByText(//)).toBeInTheDocument();
});

it('should display weeks when difference is less than a month', () => {
render(<DateDiffLabel date={new Date(2023, 5, 8)} now={now} />);
expect(screen.getByText(//)).toBeInTheDocument();
});


it('should display months when difference is less than a year', () => {
render(<DateDiffLabel date={new Date(2023, 4, 15)} now={now} />);
expect(screen.getByText(//)).toBeInTheDocument();
});

it('should display date in MM/DD format for dates within the same year', () => {
render(<DateDiffLabel date={new Date(2023, 2, 10)} now={now} />);
expect(screen.getByText('3/10')).toBeInTheDocument();
});

it('should display date in YYYY/MM/DD format for dates in a different year', () => {
render(<DateDiffLabel date={new Date(2022, 11, 25)} now={now} />);
expect(screen.getByText('2022/12/25')).toBeInTheDocument();
});
});
20 changes: 20 additions & 0 deletions src/components/ui/DateDiffLabel/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type {FC} from 'react';

import { DateToDiffLabel } from './logic';


type Prop = {
date: Date;
now?: Date;
className?: string;
};

export const DateDiffLabel: FC<Prop> = ({
date,
now = new Date(),
className,
}) => (
<time className={className} dateTime={date.toISOString()}>
{DateToDiffLabel(date, now)}
</time>
);
46 changes: 46 additions & 0 deletions src/components/ui/DateDiffLabel/logic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import {
DATE_DIFF_LABEL,
DAY,
HOUR,
MINUTE,
MONTH,
WEEK,
} from './constant';

export const DateToDiffLabel = (
date: Date,
now: Date,
): string => {
const diffInSeconds = Math.abs(
Math.floor((now.getTime() - date.getTime()) / 1000)
);

if (diffInSeconds < MINUTE)
return `${diffInSeconds}${
DATE_DIFF_LABEL['second']
}`;
if (diffInSeconds < HOUR)
return `${Math.floor(diffInSeconds / MINUTE)}${
DATE_DIFF_LABEL['minute']
}`;
if (diffInSeconds < DAY)
return `${Math.floor(diffInSeconds / HOUR)}${
DATE_DIFF_LABEL['hour']
}`;
if (diffInSeconds < WEEK)
return `${Math.floor(diffInSeconds / DAY)}${
DATE_DIFF_LABEL['day']
}`;
if (diffInSeconds < MONTH)
return `${Math.floor(diffInSeconds / WEEK)}${
DATE_DIFF_LABEL['week']
}`;
if (diffInSeconds <= MONTH * 3)
return `${Math.floor(diffInSeconds / MONTH)}${
DATE_DIFF_LABEL['month']
}`;
if(date.getFullYear() === now.getFullYear())
return `${date.getMonth()+1}/${date.getDate()}`;

return `${date.getFullYear()}/${date.getMonth()+1}/${date.getDate()}`;
};

0 comments on commit ebeb2fa

Please sign in to comment.