生年月日から現在の年齢を計算する処理を実装する際に少し詰まったので、実装方法をメモ。
うまくいかなかった例
まずはうまくいかなかった例です。
年齢をconsoleに表示するようにしてみます。
var birthday = '1996-3-6'; // 生年月日の指定
var bArr = birthday.split('-');
var birth = new Date(bArr[0], (bArr[1] - 1), bArr[2]); // 誕生日の日付
var today = new Date(); // 今日の日付
var df = today - birth; // 今日と誕生日の差(ミリ秒)
var age = Math.floor(df / 1000 / 60 / 60 / 24 / 365); // ミリ秒を年に変換(切り捨て)
console.log(age);
問題なさそうに見えたのですが、誕生日と日にちが近いときに微妙にずれることがありました。
例として誕生日を3/6、今日が3/5として試してみます。
var birthday = '1996-3-6'; // 生年月日の指定
var bArr = birthday.split('-');
var birth = new Date(bArr[0], (bArr[1] - 1), bArr[2]); // 誕生日の日付
var today = new Date(2018, (3 - 1), 5); // 2018年3月5日
var df = today - birth; // 今日と誕生日の差(ミリ秒)
var age = Math.floor(df / 1000 / 60 / 60 / 24 / 365); // ミリ秒を年に変換(切り捨て)
console.log(age);
21となるのが正しいのですが、consoleには22と表示されました。
7行目で差のミリ秒を年に変換する際に、年を365想定で行っているので、閏年の分だけ少しずれてしまうことがあるようです。
うまくいかなかった場合のデモページ2
実装方法1
閏年を想定すると少し面倒そうなので、今日と誕生日の年数の差から年齢を算出するようにしてみます。
var birthday = '1996-3-6'; // 生年月日の指定
console.log(calculate_age(birthday));
/**
* 生年月日から現在何歳かを算出する
* @param {string} birthday - 生年月日をYYYY-M-Dの形で指定
*/
function calculate_age(birthday) {
var bArr = birthday.split('-');
var today = new Date();
// 年数を比較して年齢を算出
var age = today.getFullYear() - parseFloat(bArr[0]);
// 今日と誕生日の月日を繋げてMMDDの状態にする
var b = Number(bArr[1] + adjust_digits(bArr[2], 2));
var t = Number((today.getMonth() + 1) + adjust_digits(today.getDate(), 2));
// 今日と誕生日の月日を比較して、今年の誕生日を過ぎていない場合は1をマイナスする
if(t < b) {
age--;
}
return age;
}
/**
* 0以上の整数の頭に0を追加して、指定した桁数にする
* @param {number} num - 桁数を調整する数値
* @param {number} digit - 桁数
*/
function adjust_digits(num, digit) {
var no = String(num);
while(no.length < digit) {
no = '0' + no;
}
return no;
}
単純に年数の差だと今年の誕生日を過ぎているかどうかでずれてしまうので、今年の誕生日を過ぎていない場合はマイナス1するようにしています。
うまくいった場合のデモページ1
先ほどと同様に誕生日を3/6、今日が3/5としてみて、ズレが発生しないか試してみます。
var birthday = '1996-3-6'; // 生年月日の指定
console.log(calculate_age(birthday));
/**
* 生年月日から現在何歳かを算出する
* @param {string} birthday - 生年月日をYYYY-M-Dの形で指定
*/
function calculate_age(birthday) {
var bArr = birthday.split('-');
var today = new Date(2018, (3 - 1), 5); // 2018年3月5日
// 年数を比較して年齢を算出
var age = today.getFullYear() - parseFloat(bArr[0]);
// 今日と誕生日の月日を繋げてMMDDの状態にする
var b = Number(bArr[1] + adjust_digits(bArr[2], 2));
var t = Number((today.getMonth() + 1) + adjust_digits(today.getDate(), 2));
// 今日と誕生日の月日を比較して、今年の誕生日を過ぎていない場合は1をマイナスする
if(t < b) {
age--;
}
return age;
}
/**
* 0以上の整数の頭に0を追加して、指定した桁数にする
* @param {number} num - 桁数を調整する数値
* @param {number} digit - 桁数
*/
function adjust_digits(num, digit) {
var no = String(num);
while(no.length < digit) {
no = '0' + no;
}
return no;
}
consoleには21と表示されて、意図した挙動になりました。
うまくいった場合のデモページ2
実装方法2
調べてみると、「(今日のYYYYMMDD – 誕生日のYYYYMMDD) / 10000 の小数点切り捨て」という計算方法でも算出できるようです。
var birthday = '1996-3-6'; // 生年月日の指定
console.log(calculate_age(birthday));
/**
* 生年月日から現在何歳かを算出する
* @param {string} birthday - 生年月日をYYYY-M-Dの形で指定
*/
function calculate_age(birthday) {
var bArr = birthday.split('-');
var today = new Date();
// 今日と誕生日の年月日を繋げてYYYYMMDDの状態にする
var b = Number(bArr[0] + adjust_digits(bArr[1], 2) + adjust_digits(bArr[2], 2));
var t = Number(today.getFullYear() + adjust_digits((today.getMonth() + 1), 2) + adjust_digits(today.getDate(), 2));
// 年齢の算出
var age = Math.floor((t - b) / 10000);
return age;
}
/**
* 0以上の整数の頭に0を追加して、指定した桁数にする
* @param {number} num - 桁数を調整する数値
* @param {number} digit - 桁数
*/
function adjust_digits(num, digit) {
var no = String(num);
while(no.length < digit) {
no = '0' + no;
}
return no;
}
誕生日を3/6、今日が3/5としてみて、ズレが発生しないか試してみます。
var birthday = '1996-3-6'; // 生年月日の指定
console.log(calculate_age(birthday));
/**
* 生年月日から現在何歳かを算出する
* @param {string} birthday - 生年月日をYYYY-M-Dの形で指定
*/
function calculate_age(birthday) {
var bArr = birthday.split('-');
var today = new Date(2018, (3 - 1), 5); // 2018年3月5日
// 今日と誕生日の年月日を繋げてYYYYMMDDの状態にする
var b = Number(bArr[0] + adjust_digits(bArr[1], 2) + adjust_digits(bArr[2], 2));
var t = Number(today.getFullYear() + adjust_digits((today.getMonth() + 1), 2) + adjust_digits(today.getDate(), 2));
// 年齢の算出
var age = Math.floor((t - b) / 10000);
return age;
}
/**
* 0以上の整数の頭に0を追加して、指定した桁数にする
* @param {number} num - 桁数を調整する数値
* @param {number} digit - 桁数
*/
function adjust_digits(num, digit) {
var no = String(num);
while(no.length < digit) {
no = '0' + no;
}
return no;
}
consoleには21と表示されて、意図した挙動になりました。
うまくいった場合のデモページ4
【参考サイト】
コメントが承認されるまで時間がかかります。