Help us understand the problem. What is going on with this article?

【初心者向け】JSでデータがどれだけ前のものか年や月によって書き分ける

More than 1 year has passed since last update.

はじめに

何日前の記事かだったり、何カ月前の記事か表示させたいことがある。

そこで今回はQiitaのように、ブログに対して何日前や何か月前の記事かというのを書き分けて表示させてみた。

そこで実際に使用しているutil関数を公開する。今回はTypesciprtを利用しているがJSは型がないだけなのでほとんど同じ

仕様

仕様としてはざっくり以下の通り

  1. 分、時間、日にち、年数に関しては秒から算出する
  2. 月に関しては1か月を30日と仮定する
  3. 閏年は考慮にいれない
  4. 英文法に則り、単数形と複数形は書き分ける

実装

Reactのブログに導入しているのでutil関数の入ったディレクトリからexportさせている。

const MS_PER_MINUTE = 1000 * 60;
const MS_PER_HOUR = MS_PER_MINUTE * 60;
const MS_PER_DAY = MS_PER_HOUR * 24;
const MS_PER_MONTH = MS_PER_DAY * 30;
const MS_PER_YEAR = MS_PER_DAY * 365;

export const getDifferenceDays = (postedDate: Date, baseDate: Date) => {
  const msDiff = baseDate.getTime() - postedDate.getTime();
  switch (true) {
    case msDiff < MS_PER_HOUR:
      return {
        type: 'minute',
        value: Math.floor(msDiff / MS_PER_MINUTE),
      };
    case msDiff > MS_PER_HOUR && msDiff < MS_PER_DAY:
      return {
        type: 'hour',
        value: Math.floor(msDiff / MS_PER_HOUR),
      };
    case msDiff > MS_PER_DAY && msDiff < MS_PER_MONTH:
      return {
        type: 'day',
        value: Math.floor(msDiff / MS_PER_DAY),
      };
    case msDiff > MS_PER_MONTH && msDiff < MS_PER_YEAR:
      return {
        type: 'month',
        value: Math.floor(msDiff / MS_PER_MONTH),
      };
    default:
      return {
        type: 'year',
        value: Math.floor(msDiff / MS_PER_YEAR),
      };
  }
};

export const getDifferenceTimeStr = (differenceTime: { type: string; value: number }) => {
  switch (differenceTime.type) {
    case 'year':
      return isSingular(differenceTime.value) ? `a year ago` : `${differenceTime.value} years ago`;
    case 'month':
      return isSingular(differenceTime.value) ? `a month ago` : `${differenceTime.value} months ago`;
    case 'day':
      return isSingular(differenceTime.value) ? `a day ago` : `${differenceTime.value} days ago`;
    case 'hour':
      return isSingular(differenceTime.value) ? `an hour ago` : `${differenceTime.value} hours ago`;
    case 'minute':
      return isSingular(differenceTime.value) ? `a minute ago` : `${differenceTime.value} minutes ago`;
    default:
      return ``;
  }
};

const isSingular = (num: number) => {
  return num === 1;
};

import先では以下のように利用することでan hour agoや4 days agoのような文字列が簡単に取得できる

getDifferenceTimeStr(differenceTime)

まとめ

これでベースの時間からどれだけ前の時間かをきれいに書き分けて文字列を返してくれるようにした。

もっと効率いい方法、正確に算出する方法あれば教えてください!

MikihiroSaito
Javascript好きな人。ボホール在住エンジニア。 技術関連の記事をメインに情報を発信します。 Tyepscript、React、Vue(Nuxt)、Git、Docker等
https://blog.boholabo.com
yyphp
PHPerが毎週集まり、ざっくばらんに情報交換する雑談コミュニティ
https://yyphp.connpass.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away