Edited at

2 つの Date 間の差分を求める

More than 5 years have passed since last update.

まとめて github にあげた

https://github.com/januswel/jslib

http://januswel.github.io/jslib/demo/time-distance/index.html


たとえば記事が何日前に投稿されたかを表示したい場合など。

moment.js, XDate, その他いろいろなライブラリがあるので使える場合はそっちを使うのが正解。

ただし、オトナの事情で使えないとか気に入らないとかあると思うので適当コードで概念だけ書いてみる。


月以外の差分を求める場合

年、週、日、時、分、秒、ミリ秒の場合。かんたん。

それぞれのスパンが決まりきっているのでミリ秒の差を求めてスパンのミリ秒で割る。

週、日、時、分は年・秒とほぼ同じなので省略。

結果は小数になるので適当に四捨五入などして表示するといい。


timeDistance.js

var SECOND_MILLISECOND = 1000,

MINUTE_MILLISECOND = 60 * SECOND_MILLISECOND,
HOUR_MILLISECOND = 60 * MINUTE_MILLISECOND,
DAY_MILLISECOND = 24 * HOUR_MILLISECOND,
WEEK_MILLISECOND = 7 * DAY_MILLISECOND,
YEAR_MILLISECOND = 365 * DAY_MILLISECOND;

/**
* @returns {number}
* @param {Date} src
* @param {Date} dst
*/

var yearDistance = function (src, dst) {
var deltaMillsecond = dst.getTime() - src.getTime();
return deltaMillsecond / YEAR_MILLISECOND;
},
// snip
secondDistance = function (src, dst) {
var deltaMillsecond = dst.getTime() - src.getTime();
return deltaMillsecond / SECOND_MILLISECOND;
},
millisecondDistance = function (src, dst) {
return dst.getTime() - src.getTime();
};



月の差分を求める場合

月はそれぞれでスパンが違うので 1 ミリ秒の割合が違う。

それを考慮して計算する。


monthDistance.js

var SECOND_MILLISECOND = 1000,

MINUTE_MILLISECOND = 60 * SECOND_MILLISECOND,
HOUR_MILLISECOND = 60 * MINUTE_MILLISECOND,
DAY_MILLISECOND = 24 * HOUR_MILLISECOND,
WEEK_MILLISECOND = 7 * DAY_MILLISECOND,
YEAR_MILLISECOND = 365 * DAY_MILLISECOND;

/**
* @return {number}
* @param {number} year
* @param {number} month
*/

var getNumberOfDaysForMonth = function (year, month) {
return new Date(year, month + 1, 0).getDate()
},
/**
* @returns {number}
* @param {Date} src
* @param {Date} dst
*/

monthDistance = function (src, dst) {
var deltaYear = dst.getFullYear() - src.getFullYear(),
deltaMonth = deltaYear * 12 + dst.getMonth() - src.getMonth(),
srcOffsetMilliseconds = src.getDate() * DAY_MILLISECOND + src.getHours() * HOUR_MILLISECOND + src.getMinutes() * MINUTE_MILLISECOND + src.getSeconds() * SECOND_MILLISECOND + src.getMilliseconds(),
srcNumberOfDaysForMonth = getNumberOfDaysForMonth(src.getFullYear(), src.getMonth() + 1),
srcOffsetRate = srcOffsetMilliseconds / (srcNumberOfDaysForMonth * DAY_MILLISECOND),
dstOffsetMilliseconds = dst.getDate() * DAY_MILLISECOND + dst.getHours() * HOUR_MILLISECOND + dst.getMinutes() * MINUTE_MILLISECOND + dst.getSeconds() * SECOND_MILLISECOND + dst.getMilliseconds(),
dstNumberOfDaysForMonth = getNumberOfDaysForMonth(dst.getFullYear(), dst.getMonth() + 1),
dstOffsetRate = dstOffsetMilliseconds / (dstNumberOfDaysForMonth * DAY_MILLISECOND);

return deltaMonth - srcOffsetRate + dstOffsetRate;
};


Date を使って大雑把な月計算をしたあと、日単位のオフセットを引いたり足したりする。

2013/01/10 〜 2013/07/20 の期間を求めたい場合、 2013/01/01 から 2013/07/01 までを計算したあと、 2013/01/01 〜 2013/01/10 までを引き、 2013/07/01 〜 2013/07/20 を足す。