今回は、WEBサイトに、ユーザーが選択した日時から現在日までの日数を計算し表示してみたいと思います。
現在日時から特定の過去の日時を引き算することになります。
遊び心で、生まれた日から現在までの日数を計算してみることもできます。
他の用途としては、最後に何かをした日からどれだけの日数が経っているのか、ダイエット期間を計算したり、何かの記念日計算したりするのに使用可能かもしれません。
使用するもの
- HTMLファイル(各種ファイルと、jQuery及び、日付入力に使用するjQuery UI Datepickerを読み込みます。)
- CSSファイル(ほぼ装飾なし、多少の見栄えのみ調整しています。)
- JSファイル
jQuery UI Datepickerの詳細な使用方法・オプション等については下記の記事を参考にしてください。
実装手順概要
①現在日を取得し、年、月、日付、曜日をそれぞれ変数に代入 し、成形してHTML の現在日の要素に表示
②下記③~⑥までを処理する関数を作成
③Datapickerから入力された日付をData型に変換
④現在日の経過ミリ秒から入力された日付の経過ミリ秒を差し引く
⑤差し引いた経過ミリ秒を日数に計算
⑥jQueryのtextメソッドでHTMLの日数の要素を更新
⑦自作関数を、Datapickerのオプションで日付が選択された時に実行
CODEPEN で実装と確認
「Run Pen」をクリックしてください。
See the Pen day of start to today by blue moon (@blue-moon) on CodePen.
HTMLファイル
<head>
<!-- 省略 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/themes/start/jquery-ui.min.css"> <!-- Datepickerのテーマstartを選択 -->
<link rel="stylesheet" href="style.css"> <!-- ご自身のパスに変更 -->
</head>
<body>
<!--今日の日時 -->
<div id=today class="container">
<div class="today">本日 : </div>
<span></span>
</div>
<!-- 開始日 -->
<div id=start class="container">
<div class="today">開始日 : </div>
<span><input type="text" id="datepicker"></span>
</div>
<!-- 経過日数 -->
<div id=count class="container">
<p>経過日数 : </p>
<div class="today">
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script> <!-- Datepicker -->
<script src="main.js"></script> <!-- ご自身のパスに変更 -->
</body>
補足説明
Datapicker のテーマは25種類程ありますので、お好みのものを選択してください。
詳細については、「使用する項目」で紹介した記事をご参考にしてください。
CSSファイル
body {
margin: 20px;
font-family: monospace;
font-size: 13px;
}
p {
margin: 0;
}
.container {
margin: 0.7rem;
display: flex;
align-items: center;
}
input {
width: 140px; /* カレンダーの大きさに合わせて調整 */
font-family: monospace;
font-size: 13px;
}
#ui-datepicker-div {
transform: scale(0.6) translate(-34%, -33%); /* デフォルトのカレンダーが大きいため調整 */
left: 90px !important;
top: 63.5px !important;
}
.ui-datepicker-current.ui-state-default.ui-priority-secondary.ui-corner-all {
display: none; /* Todayボタン非表示 */
}
補足説明
Datepicker のデフォルトのカレンダーは大き目でしたので、大きさを調整しています。
そうすると、その分入力フォームとの距離が生じてしまうため、そちらも合わせて調整しています。
一方、入力フォームの方も大きさを調整したカレンダーの幅に合わせています。
両方を調整しながら、落としどころを見つけてください。
JSファイル
処理内容を大まかに分けると、記事の最初の「実装手順概要」項目と多少内容が被りますが、以下のようになります。
- 現在日を取得し表示する処理
- 選択された日付を取得し表示する処理
- それぞれの日付の差を計算し表示する処理
- Datapickerのオプション(関数を呼出しも含む)追加
/* 現在日時を取得し表示 */
const today = new Date(); // 現在日時を取得
const year = today.getFullYear(); // 年を取得
const month = today.getMonth() + 1; // 月を取得(0~11)
const date = today.getDate(); // 日付を取得
const day = today.getDay(); // 曜日を取得(0~6)
const wArray = [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ] ; // 曜日の配列を作成
const wDay = wArray[day]; // 曜日短縮形の配列
console.log(today); // 取得した現在日時を確認(削除可)
$('#today span').text(year + '/' + month + '/' + date + '(' + wDay + ')'); // HTMLの要素にテキスト挿入)
/* datepickerから選択された日付を取得し表示する関数 */
const countUp = () => {
const startDayStr = $('#start input').val(); // カレンダーから選択された日付(テキスト)を取得
const startDayNum = new Date(startDayStr); // カレンダーから選択された日付をデータ型に変換
console.log(startDayStr); // 入力した日を確認(削除可)
console.log(startDayNum); // 入力した日を確認(削除可)
/* 現在日の経過ミリ秒から選択日の経過ミリ秒を差し引く */
const elToday = today.getTime(); // 基準日付時間(1970年1月1日)からの経過ミリ秒取得
const elstartDay = startDayNum.getTime(); // 基準日付時間(1970年1月1日)からの経過ミリ秒取得
const count = elToday - elstartDay; // 各経過ミリ秒の差を計算
const countDate = (Math.trunc(count / 24 / 60 / 60 / 1000)); // 経過ミリ秒の差を日数に変換
console.log(elToday); // 経過ミリ秒を確認(削除可)
console.log(elstartDay); // 経過ミリ秒を確認(削除可)
console.log(count); // 経過ミリ秒の差を確認(削除可)
$('#count .today').text(countDate + '日');
};
/* datepickerのオプション */
$('#datepicker').datepicker({
dateFormat: 'yy/mm/dd(D)', // 2021/08/27(Fri)
duration: 500, // 500ミリ秒かけて表示
closeText: 'close', // カレンダーを閉じるボタンに表示するテキスト
maxDate: 0, // 選択可能な最大日(将来日)、0は当日までしか選択できない
onSelect: countUp, // 日付選択後に呼び出す関数
selectOtherMonths: true, // 当月前後の日付選択可能
showAnim: 'slideDown', // スライドダウンでカレンダー表示
showOtherMonths: true, // 当月カレンダーに前後月の日を表示
showButtonPanel: true, // 選択後にボタンを表示
});
補足説明
①getTime()
基準日付時間(1970年1月1日)からの経過ミリ秒取得を取得しています。
現在日時及び期限日時それぞれ取得した経過ミリ秒の差を、日数に変換処理しています。
因みにこの基準日時はUTC(協定世界時)であるため、どのタイムゾーンであってもgetTime()メソッドは同じ値を取得します。
②Math.trunc()
JavaScriptの組み込みのオブジェクトで、小数点以下を切り捨てます。
詳細は、MDN JavaScript Math をご参照下さい。
③datepickerのオプション
onSelect で、先に作成しておいた自作関数countUpを呼び出しています。このオプションは、 選択した日付をテキスト型として受け取るため、 自作関数 countUp ではデータ型に変更する処理が必要になります。
showButtonPanel を trueにし、カレンダー下のボタンを表示していますが、「Close」とボタン名を変更した閉じる方のボタンはそのまま表示し、「Today」ボタンは非表示にしています。このボタンは前回の記事にも記載したのですが、日付選択ボタンではないためです。
「Close」 ボタンは、再度入力フォームをクリックした時にカレンダーが開いてしまい、再度日付を選択しないと閉じないため、あった方がよいかと思いました。
【余談】2038年問題
基準日時UTC からの経過ミリ秒にも限界があるようです。
協定世界時における1970年1月1日0時0分0秒(日本標準時では1970年1月1日9時0分0秒)から2,147,483,647秒を経過した、2038年1月19日3時14分7秒(日本標準時では2038年1月19日12時14分7秒、閏秒は考慮していない)を過ぎると、この値がオーバーフローし、負と扱われる[注釈 2]ため、もし時刻を正しく扱えていることを前提としたコードがあれば、誤動作する。
ウィキペディア 2038年問題より引用
よって、まだなかり先の話にはなりますが、2038年1月以降(このブログ投稿日は2021年8月ですが)まで運用予定のサイトを作成される場合はご注意ください。
しかし、そのころには何か対応プログラムができているでしょう。そうでないと、例えば金融機関の利息計算等に不具合が発生したりすると困りますね。
金融機関のシステム開発は大規模プロジェクトは、数年にわたり、金額も桁違いで、何段階かのフェーズに分けて慎重に行われます。因みに、某青い銀行でかかった費用は4,000億円だそうです。
それでも、不具合が発生したりするので怖いです。キャッシュカードがATMに飲み込まれたらどうしようと不安になります。
最後に
このプログラムが完成した暁には、生まれた日を入力してみると面白いかもしれません。生まれた日の曜日も分かります。
しかし、さすがにprevボタンで月を遡るのは辛いと思いますので、Datepickerのオプションで、年と月をドロップダウン形式に変更するとよいと思います。