目次
はじまり
クライアントから創業から〇〇年△△日のような表記を設定して欲しい言われました。
安易に「おかのした!」と回答したら、うるう年が絡んできて厄介な仕組みだと頭を抱えました。
今回は、JavaScriptを使って期間内の日数を取得する方法を記事にしたいと思います。
日付けライブラリの殿堂 Moment.js を利用します。
環境
この記事は、以下の管理人の検証環境をもとにして記事にしています。
| Moment.js | 2.29.1 |
導入方法
管理人が行った、動作確認サンプルを実装するために、以下の手順でソースコードを導入していきます。
スクリプト
//開始日付け
const baseDay = moment('2012-03-01');
//今日の日付け
const today = moment();
//うるう年を判定
function isLeapYear(year){
return (year%4 == 0 && year%100 != 0) || year%400 == 0;
}
//うるう年分の追加日付けを求める
let LeapYearAddCount = 0;
for(let year=baseDay.get('year'); year<today.get('year'); year++){
if(isLeapYear(year))
LeapYearAddCount = LeapYearAddCount + 1;
}
//調整日数
//開始日がうるう年だったら-1
if(isLeapYear(baseDay.get('year')))
LeapYearAddCount = LeapYearAddCount-1;
//終了日がうるう年だったら+1
if(isLeapYear(today.get('year')))
LeapYearAddCount = LeapYearAddCount+1;
//開始日付け と 今日の日付け の日数を求める
const duration = moment.duration(today.diff(baseDay));
//差引きの日数
const remainderDays = duration.as('day') - ((365*duration.get('y'))+LeapYearAddCount);
//HTMLに値を設定
let spanEl = document.getElementById('span');
let dateEl = document.getElementById('date');
spanEl.innerText = baseDay.format("YYYY年MM月DD日")+" から "+today.format("YYYY年MM月DD日")+" の日数は";
dateEl.innerText = duration.get('y')+"年"+Math.floor(remainderDays)+"日("+Math.floor(duration.asDays())+"日)です。";
HTML
<div id="area"> <p id="span"></p> <div id="date"></div> </div> <script type="text/javascript" src="https://momentjs.com/downloads/moment.js"></script>
サンプル
今回のソースを実際に触って確認できるようにデモを用意しました。
See the Pen 期間の日数を求める by カバの樹 (@kabanoki) on CodePen.dark
解説
今回のサンプルは以下の流れに沿って実装しています。
step
1期間設定
まず期間となる開始の日付けと終了となる今日を日付けを設定します。
//開始日付け
const baseDay = moment('2012-3-1');
//今日の日付け
const today = moment();
step
2うるう年を判定
期間内の年をループで回し、うるう年の判定をする。
うるう年が発生するたびに1を追加する。
この時に注意するのは、今日の日付けの年度を含めないことです。
うるう年の判定を以下を参考にしてます。
(1)西暦年号が4で割り切れる年をうるう年とする。
(2)(1)の例外として、西暦年号が100で割り切れて400で割り切れない年は平年とする。
質問3-6)どの年がうるう年になるの?
https://www.nao.ac.jp/faq/a0306.html
//うるう年分の追加日付けを求める
function isLeapYear(year){
return (year%4 == 0 && year%100 != 0) || year%400 == 0;
}
let LeapYearAddCount = 0;
for(let year=baseDay.get('year'); year<today.get('year'); year++){
if(isLeapYear(year))
LeapYearAddCount = LeapYearAddCount + 1;
}
step
3うるう年の追加日付けの調整
開始日付けもしくは終了日付けがうるう年の場合は、追加日付けに調整を入れる必要があります。
//調整日数
//開始日がうるう年だったら-1
if(isLeapYear(baseDay.get('year')))
LeapYearAddCount = LeapYearAddCount-1;
//終了日がうるう年だったら+1
if(isLeapYear(today.get('year')))
LeapYearAddCount = LeapYearAddCount+1;
step
4期間の差引きで日付けを取得する
Moment.js の duration を使って期間の差引きを取得します。
https://momentjs.com/docs/#/durations/
//開始日付け と 今日の日付け の日数を求める
const duration = moment.duration(today.diff(baseDay));
//差引きの日数
const remainderDays = duration.as('day') - ((365*duration.get('y'))+LeapYearAddCount);
step
5差引きの日数を表示
取得した差引きの日数をHTMLに出力する。
//HTMLに値を設定
let spanEl = document.getElementById('span');
let dateEl = document.getElementById('date');
spanEl.innerText = baseDay.format("YYYY年MM月DD日")+" から "+today.format("YYYY年MM月DD日")+" の日数は";
dateEl.innerText = duration.get('y')+"年"+Math.floor(remainderDays)+"日("+Math.floor(duration.asDays())+"日)です。";