Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

traQ上のメッセージの投稿・編集日時に年月日を適宜省略しつつ付け足す #4338

Merged
merged 8 commits into from
Jul 22, 2024
23 changes: 18 additions & 5 deletions src/lib/basic/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,25 @@ export const getDateRepresentationWithoutSameDate = (
}

export const getDisplayDate = (createdAt: string, updatedAt: string) => {
const createdDate = new Date(createdAt)
if (createdAt === updatedAt) {
return getTimeString(createdDate)
let displayDate = new Date(createdAt)
if (createdAt !== updatedAt) {
displayDate = new Date(updatedAt)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imo: 3項演算子使った方がシンプルに書けそうな気がします:eyes:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

というかこれ常にnew Date(updatedAt)で良くないですか?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

確かに三項演算子は使えますね。修正前のコードの構造に気を取られて気付かなかったです。
メッセージの投稿直後に updatedAt = createdAt として定義してくれているなら単に1行

displayDate = new Date(updatedAt)

でも良さそうには思えたのですが、その確証がなかったので残しました。これを採用すると createdAt を引数にとる必要がなくなります

const today = new Date()
const timeString = getTimeString(displayDate)
const yesterday = new Date(today)
yesterday.setDate(today.getDate() - 1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imo: あんまり再代入したくない気持ちがある

const yesterday = new Date(today.getTime() - 1000 * 60 * 60 * 24)


if (getFullDayString(displayDate) === getFullDayString(today)) {
return '今日' + ' ' + timeString
}
if (getFullDayString(displayDate) === getFullDayString(yesterday)) {
return '昨日' + ' ' + timeString
}
if (displayDate.getFullYear() === today.getFullYear()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここから上は年が同じである条件はおなじなのでネストは増えるけど条件をまとめられそうです

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

文意をうまく汲み取れていないかもですが、こういうことですか…?

if (
  displayDate.getFullYear() === yesterday.getFullYear() &&
  displayDate.getMonth() === yesterday.getMonth() &&
  displayDate.getDate() === yesterday.getDate()
) {
  return '昨日' + ' ' + timeString
}
if (displayDate.getFullYear() === today.getFullYear()) {
  if (
    displayDate.getMonth() === today.getMonth() &&
    displayDate.getDate() === today.getDate()
  ) {
    return '今日' + ' ' + timeString
  }
  return getDayString(displayDate) + ' ' + timeString
}
return getFullDayString(displayDate) + ' ' + timeString

大晦日のメッセージを元日に閲覧する時には『20XX/12/31』ではなく『昨日』と表示されてほしいので、年が同じである条件をまとめるならばそれより先に『昨日』の判定を書くことになります。

しかし個人的には、メッセージの投稿日時が
『今日』かどうか →『昨日』かどうか →『今年』かどうか
と順に遡りつつ判定していく構造を保った方が整理された実装に見えるような気がします…。どうでしょうか?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

↑のコードの想定でした
todayとyesterday混同しててもう少し単純なコードになると勘違いしてました🙏

それを踏まえても個人的にはtodayの比較とyesterdayの比較が交互に来るよりもyesterdayの比較→todayの比較の順に比較できる↑の実装が見やすいと感じますが、さっきの文字列で比較しないで欲しいという指摘ほど強い思いはないので任せます

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

や、共通化のことだけを考えてたんですが拡張性が低くなるのでやっぱり現在に近い順に記述するままでいいです🙇🙇🙇

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

了解です。レビューありがとうございます!

return getDayString(displayDate) + ' ' + timeString
} else {
const updatedDate = new Date(updatedAt)
return getDateRepresentationWithoutSameDate(updatedDate, createdDate)
return getFullDayString(displayDate) + ' ' + timeString
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここはフォーマット後の文字列を比較するより素直に年月日を比較してフォーマットを決めるのが他の関数の中身を読む手間を減らせて分かりやすそうです

}

Expand Down
35 changes: 25 additions & 10 deletions tests/unit/lib/basic/date.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,18 +94,33 @@ describe('getDateRepresentationWithoutSameDate', () => {
})

describe('getDisplayDate', () => {
const dateISO = '2001-04-04T05:20:34'

it('should get time string when not modified', () => {
expect(getDisplayDate(dateISO, dateISO)).toBe('05:20')
beforeEach(() => {
vi.useFakeTimers()
})
it('should get time string when same date', () => {
const dateISO2 = '2001-04-04T08:25:34'
expect(getDisplayDate(dateISO, dateISO2)).toBe('08:25')
afterEach(() => {
vi.useRealTimers()
})
it('should get date string when not same date', () => {
const dateISO2 = '2001-06-04T08:25:34'
expect(getDisplayDate(dateISO, dateISO2)).toBe('06/04 08:25')

const createdDateISO = '2010-04-01T12:34:56'
const updatedDateISO = '2010-05-02T14:28:57'

it('should say 今日 when updated today', () => {
vi.setSystemTime('2010-05-02T15:00:00')
expect(getDisplayDate(createdDateISO, updatedDateISO)).toBe('今日 14:28')
})
it('should say 昨日 when updated yesterday', () => {
vi.setSystemTime('2010-05-03T15:00:00')
expect(getDisplayDate(createdDateISO, updatedDateISO)).toBe('昨日 14:28')
})
it('should get MM/DD when updated in the same year', () => {
vi.setSystemTime('2010-07-07T15:00:00')
expect(getDisplayDate(createdDateISO, updatedDateISO)).toBe('05/02 14:28')
})
it('should get YYYY/MM/DD when updated before last year', () => {
vi.setSystemTime('2015-10-10T15:00:00')
expect(getDisplayDate(createdDateISO, updatedDateISO)).toBe(
'2010/05/02 14:28'
)
})
})

Expand Down
Loading