2023年10月5日木曜日

apex.dateを使用して日付の計算を行う

入力項目として開始日と経過日数が画面にあり、経過日数を入力した時点で終了予定日を計算し、画面に表示したいとの相談がありました。

簡単そうに思える実装ですが、画面上での日付計算はJavaScriptで記述する必要があります。しかし、画面に表示されている日付は、オラクル・データベースによって日付書式が適用されて、文字列として生成されています。

JavaScriptでの日付書式(日付フォーマットと呼んでいることが多いようです)とオラクル・データベースの日付書式は異なります。この違いを吸収するためにOracle APEXでは、JavaScript APIとしてapex.dateを提供しています。APIの説明は以下を参照してください。

https://docs.oracle.com/en/database/oracle/apex/23.1/aexjs/apex.date.html

このapex.dateを使って、開始日と経過日数から終了予定日を求める実装を行なってみます。

作成するアプリケーションは以下のように動作します。


本記事で紹介している内容は、Jon Dixsonさんの以下のブログ記事を参考にしています。

Easy Date Handling in JavaScript with apex.date
Example 1 - Date Calculations

元記事には日付の比較や経過日数(since)の使い方などapex.dateの他の用法も紹介されているので、ぜひ参照してください。

ほとんどJon Dixsonさんの記事のままですが、サンプルのアプリケーションの実装を説明します。

空のアプリケーションを作成し、ホーム・ページにすべて実装します。

開始日となるページ・アイテムをP1_START_DATEとして作成します。タイプ日付ピッカーを選択します。ラベル開始日とします。


経過日数となるページ・アイテムをP1_DAYSとして作成します。タイプ数値フィールドを選択します。ラベル経過日数とします。


開始日に経過日数を加えた日付を設定するページ・アイテムを、P1_END_DATEとして作成します。タイプ表示のみを選択します。ラベル終了予定日とします。


経過日数の値が変更されたときに終了予定日が設定されるように、ページ・アイテムP1_DAYS動的アクションを作成します。

識別名前終了日の更新とします。タイミングイベント変更選択タイプアイテムアイテムP1_DAYSになります。これでP1_DAYSが変更されたときに、TRUEアクションが実行されます。


TRUEアクションとしてJavaScriptコードの実行を選択します。設定コードに以下を記述します。

/*
* Jon Dixsonさんのブログ記事を参照しています。
*
* Easy Date Handling in JavaScript with apex.date
* https://blog.cloudnueva.com/apex-date-js-api
* Example 1 - Date Calculations
*
* apex.dateのリファレンスは以下。
* https://docs.oracle.com/en/database/oracle/apex/23.1/aexjs/apex.date.html
*/
/*
* アプリケーション定義のアプリケーション日付書式を取り出します。
* ページ・アイテムに個別に日付書式を設定している場合は、dateFormatは
* その値を指定します。また、apex.date.parseはオラクル・データベースの
* 一部の日付書式をサポートしていません。(詳細はリファレンスを確認のこと)。
*/
const dateFormat = apex.locale.getDateFormat();
// 経過日数を取り出し数値に変換します。(ページ・アイテムの値は文字です。)
const addDays = Number(apex.items.P1_DAYS.value);
// 開始日の文字列を日付書式に従ってJavaScriptのDateオブジェクトとして取り出します。
let startDate = apex.date.parse(apex.items.P1_START_DATE.value, dateFormat);
// 経過日数を加えて終了予定日とします。
let endDate = apex.date.add(startDate, addDays, apex.date.UNIT.DAY);
// 終了予定日を指定した日付書式で文字列に変換します。
let endDateStr = apex.date.format(endDate, dateFormat);
// 得られた終了予定日の文字列をページ・アイテムに設定します。
apex.items.P1_END_DATE.setValue(endDateStr);


以上で実装は完了です。アプリケーションを実行すると、記事の先頭のGIF動画のように動作します。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/sample-apex-date.zip

以上になります。

Oracle APEXのアプリケーション作成の参考になれば幸いです。