選択肢が少ないということは幸せなことなんだよ。

この記事はQiitaとのクロス投稿です

発端

眠れないなーと思いつつスマホでこちらの記事を読みながら、
令和へ対応せよ!元号のアルゴリズム - Qiita

年*10000 + 月*100 + 日  

あー、こんなコードって大昔に(VBAとかで)書いたんだか見たんだかしたことあるなーと思ったので、
自分ならどう書くかなーと思ったので殴り書き。

年月日に乗算して計算するのはバッドプラクティス

…だと思っています。月*100ではないですし、私は違和感があります。

端的に言うと、
データベースの数値型のカラムに数値で日付が入っていたらどう思うか?ってことです。^1

というわけで書いてみた

function ymdToGengo(y, m, d) {  
  // TODO 引数チェック  
  const ts = new Date(`${y}-${('0'+m).slice(-2)}-${('0'+d).slice(-2)}T00:00:00.000+0900`).getTime();  
  if (ts >= new Date('2019-05-01T00:00:00.000+0900').getTime()) {  
    return '令和';  
  }  
  if (ts >= new Date('1989-01-08T00:00:00.000+0900').getTime()) {  
    return '平成';  
  }  
  if (ts >= new Date('1926-12-25T00:00:00.000+0900').getTime()) {  
    return '昭和';  
  }  
  return '大正以前';  
}  

console.assert(ymdToGengo(0, 1, 1) === '大正以前');  
console.assert(ymdToGengo(1926, 12, 25) === '昭和');  
console.assert(ymdToGengo(1989, 1, 8) === '平成');  
console.assert(ymdToGengo(2019, 5, 1) === '令和');  
  • 元のお題では年月日の数字がそれぞれあるっていう話だったので、引数はYMDで
    • 直接Dateを受け取るようにすれば、別のタイムゾーンで入ってきた日付も正常に判定できるはず
  • 比較はDateで比較対象作ってからtimestampで比較
  • ガード節を使おうぜ

気付き

console.log(new Date('2019-05-01T00:00:00.000+0900').toLocaleDateString('ja-JP-u-ca-japanese', {era:'long'}));  
// 平成31年5月1日  
  • でも手元のnode(v8.11.2)だと取れなかった(CE 2019 5 1と出力された)^3
  • Chromeもまだ令和未対応
  • こうやって考えるとPHPのDateTimeって使い勝手いいよな

結論

もしnpmに元号変換ライブラリがあったらそれ使う。[^4]

[^4]: このへん? https://github.com/yukik/koyomi

この記事へのコメント

まだコメントはありません