2020/01/31: バグ発見によりコード修正
JavaScriptで何歳何ヶ月を計算させたい
問題提起
年齢計算で検索するとたいていmoment().diff(birthday, 'years')
でn歳です!
だけの記事が出てくる。(探せば色々あるけど)
やりたいこと
moment.jsを使って生年月日から何歳何ヶ月という情報を出したい
結論
import moment from 'moment'
const birthday = '1996-01-01' // 本来はここに生年月日データを当てはめる
const today = moment()
// 12で割って年を出す
let y = Math.floor(moment.duration(today.diff(birthday)).as('months') / 12)
// 12で割った余りで月を出す
let m = Math.floor(moment.duration(today.diff(birthday)).as('months') % 12)
// マイナス値であれば0を再代入する
y = Math.sign(y) !== -1 ? y : 0
m = Math.sign(m) !== -1 ? m : 0
const age = y + '歳' + m + 'ヶ月'
console.log(age) // y歳mヶ月
応用 死んだ日付を加味した年齢
import moment from 'moment'
const birthday = '1996-01-01' // 本来はここに生年月日データを当てはめる
const deathday = deathday // 死んだ日付はNULLの可能性あり
// 生きている最新の日付
const latestDate = deathday ? moment(deathday) : moment()
// 12で割って年を出す
let y = Math.floor(moment.duration(latestDate.diff(birthday)).as('months') / 12)
// 12で割った余りで月を出す
let m = Math.floor(moment.duration(latestDate.diff(birthday)).as('months') % 12)
// マイナス値であれば0を再代入する
y = Math.sign(y) !== -1 ? y : 0
m = Math.sign(m) !== -1 ? m : 0
const age = y + '歳' + m + 'ヶ月'
console.log(age) // y歳mヶ月
結論:::修正前の駄目な例
1ヶ月のズレやマイナス値など様々なバグが出る
特にconst y = today.diff(birthday, 'years')
はきっちり1年を出せないなどの問題が発覚
import moment from 'moment'
const birthday = '1996-01-01' // 本来はここに生年月日データを当てはめる
const today = moment()
const y = today.diff(birthday, 'years')
const m = Math.floor(moment.duration(today.diff(birthday)).as('months') % 12)
const age = y + '歳' + m + 'ヶ月'
console.log(age) // y歳mヶ月
解説:::修正前の解説
import moment from 'moment'
const birthday = '1996-01-01' // 本来はここに生年月日データを当てはめる
const today = moment()
const y = today.diff(birthday, 'years')
const m = Math.floor(moment.duration(today.diff(birthday)).as('months') % 12)
const age = y + '歳' + m + 'ヶ月'
console.log(age) // y歳mヶ月
// #### それぞれ時点の値 ####
// 1996年1月1日0時00分00秒からのミリ秒差分
today.diff(birthday) // 756908681438 ミリ秒
// momentのduration関数で期間オブジェクトに変換
moment.duration(today.diff(birthday))
// 期間を月指定で出力
moment.duration(today.diff(birthday)).as('months') // 287.82577535549063 ヶ月
// 上述の値を12で割った余りを出します。
// 小数点がありますがこれがy歳mヶ月のmになります
moment.duration(today.diff(birthday)).as('months') % 12 // 11.82605117984781
// Math.floorで小数点を省いて月の完成
Math.floor(moment.duration(today.diff(birthday)).as('months') % 12) // 11 ヶ月