質問: javascriptで指定日からの年月日計算の仕方
回答: こんばんわ ゚▽^)o -*-*-*◇ 補足に対して ◇*-*-*- 月数の指定値は 0 ~ 11 の数なので 12 月の場合は 11 を指定します。 補足のように ┌──────── | var begin = new Date(2012,12,05); └──────── と指定した結果「1年と28日」と表示されるのは、 月数が 12 を指定してしまっているので、 「13 月」になってしまっているからです。 なので、 ひと月後の「2013 年 1 月 5 日」からのカウントになり、 経過月数が 0 ヶ月 になります。 12 月からのカウントにするには、 正しくは、 ┌──────── | var begin = new Date(2012,11,5); └──────── のように指定しますヽ(・ω・* -*-*-*◆ Date() の年月日指定 ◆*-*-*- Date() オブジェクトの年月日指定が間違っています。 Date() オブジェクトの宣言で年月日を指定するには、 指定の形式がいくつかあります。 [ ] ┌──────── | new Date('月 日,年 時:分:秒'); └──────── の形で指定する場合は、 月数は 12 のような数字ではなく ┌──────── | new Date('Dec 15,2003 00:00:00'); └──────── のようなアルファベットで指定します。 ただ、 今回は時刻の取得は必要ないので、 ┌──────── | new Date(年, 月, 日); └──────── で取得するのが簡単です。 このとき、 月数は 0 ~ 11 の数で指定するので、 12月は 11 を指定することになります・ω・)o ┌──────── | new Date(2003, 11, 15); └──────── -*-*-*◆ 年の取得 ◆*-*-*- Javascript で「年」を取得するとき、 getYear() は、 2000 年より前か後かやブラウザの違いによって 取得できる値がまちまちになるので、 扱いがとても面倒くさいです。 年を取得する場合には、 「getFullYear()」を使うようにしましょう。 -*-*-*◆ うるう年 ◆*-*-*- 年数の計算の際に、 「getYear()」で年数を出してから それぞれを引き算しているので、 基本的には、 「うるう年」による日数の狂いは気にしなくていいです。 ただし、 ┌──────── | [誕生日] の日数 > [現在] の日数 └──────── の場合、 現在の月が「3月」のときだけ 「うるう年計算」が必要になります・ω・) ┌──────── | [誕生日]の月数が | 「2月」かどうかに関わらず、 | 「現在」の月が「3月」の場合には、 | 今年がうるう年がどうか判定が必要です。 └──────── 質問のソースでは、 この「うるう年」計算を、 「4の倍数かどうか」だけで計算していますが、 「うるう年」の条件はそれだけではないので、 計算方法が間違っています。 「うるう年」は ┌──────── | 1. 西暦年が4で割り切れる年は閏年 | 2. ただし、西暦年が100で割り切れる年は平年 | 3. ただし、西暦年が400で割り切れる年は閏年 └──────── というふうに決められているので、 正しくは、 これらの条件を判定する計算が必要になります。 上記の条件をもとに 「うるう年」かどうかを判定するには、 下記のような手順で評価すればイイと思います♪ ┌──────── | [ 400 で割り切れる? ] ─( YES )→ うるう年 | . . . .| | . . ( NO ) | . . . .↓ | [ 100 で割り切れるか? ] ─( YES )→ 平年 | . . . .| | . . ( NO ) | . . . .↓ | [ 4 で割り切れるか? ] ─( YES )→ うるう年 | . . . .| | . . ( NO ) | . . . .↓ | . . . 平年 └──────── これを Javascript でやろうとすれば、 ┌──────── | var uruu = | ( Year%400==0 ) ? true : | ( Year%100==0 ) ? false : | ( Year%4==0 ) ? true : false; └──────── のように条件分岐して、 変数 uruu が「true」なら「うるう年」、 「false」なら「うるう年ではない」、 というふうになりますo(・ω・* -*-*-*◆ 足りない計算 ◆*-*-*- 質問のソースで、 やらないといけない計算が一つ抜けています。 ┌──────── | [誕生日] の月数 > [現在] の月数 └──────── の場合、たとえば ┌──────── | 2008 年 11 月 ~ 2014 年 1 月 └──────── のような場合 日数のときと同様に、 年数から 1 を引いて、 月数に 12 を足さないといけません。 -*-*-*◆ ソースの修正案 ◆*-*-*- 以上の修正点の他に、 ソースの記述の細かな修正を加えて、 全体の修正案を示します。 なお、 変数名も、 あたしが個人的に分かりやすい変数名に変えるので、 参考にするときは 使いやすい変数名にもどしてください(^^; ┌──────── /*==== 日付オブジェクト =====*/ var now = new Date(); var begin = new Date(2003,11,15); /*==== 年数 ====*/ var nowY = now.getFullYear(); var beginY = begin.getFullYear(); var Y = nowY - beginY; /*==== 月数 ====*/ var nowM = now.getMonth(); var beginM = begin.getMonth(); var M = nowM - beginM; //> 月数がマイナスの場合 if(M<0){ Y--; M += 12; } /*==== 日数 ====*/ var D = now.getDate() - begin.getDate(); //> 日数がマイナスの場合 if(D<0){ M--; if(M<0){ Y--; M += 12 } nowM--; if(nowM<0){ nowY--; nowM += 12; } //> 各月の日数をリスト化 var days = [31,28,31,30,31,30,31,31,30,31,30,31]; //> うるう年判定 var uruu = ( nowY%400==0 ) ? true : ( nowY%100==0 ) ? false : ( nowY%4==0 ) ? true : false; if(uruu){ days[1] = 29; } //> 日数修正 D += days[nowM]; } /*==== 表示 ====*/ var time = Y+"年"; if(M){ time += M+"ヶ月";} if(D){ time += "と"+D+"日";} document.write("開始より今日までで"+time+"経ちました。"); └────────