新規投稿
フォローする

日付の計算時に、土日祝日であれば直前の平日を指定する

kintoneで業務システム作るときには、

「締め日」に「支払サイト」の日数を加算して「支払期日」を算出

なんて処理をよく作ると思います。

 

そのときに、支払期日が休日(土日・祝日)だったら、

直前の平日を指定したい、なんて要件がけっこうあるんじゃないかと。

そんなとき、

・祝日をどう判定するのか?

・祝日の前日がまた祝日だったら?

辺りも考慮する必要があって、ちょっと厄介です。

 

Cybozu CDNでは「moment.js」や「UltraDate.js」が紹介されてますが、

もっとシンプルに書ける「date-fns」と「holiday_jp-js」の組み合わせで実装してみたのんで、紹介します。

 

https://date-fns.org/docs

https://github.com/holiday-jp/holiday_jp-js

 

ライブラリの準備

date-fnsはCDNが公開されてます。

https://cdnjs.com/libraries/date-fns

 

holiday-jpはこいつをダウンロード。

https://raw.githubusercontent.com/holiday-jp/holiday_jp-js/master/release/holiday_jp.min.js

 

kintoneアプリの初期設定

こんな風に、数値1つ、日付3つのシンプルなアプリを作り、

フィールド名=フィールドコードにしておきます。

(入力禁止制約はJSで作ります)

 

JSカスタマイズの設定は、

自作の「latest-weekday.js」と合わせて、こんな風に設定します。

JSを書く

「latest-weekday.js」の中身はこちら。

一番ポイントは「latestWeekday()」関数で、再帰的に土日 or 祝日を判定しております。

(function() {
'use strict';

// 直前の平日を取得
const latestWeekday = function(date) {
if (dateFns.isWeekend(date) || holiday_jp.isHoliday(date)) {
const prevDate = dateFns.subDays(date, 1);
return latestWeekday(prevDate);
}
return date;
};

// 日付を加算
const addDays = function(date, days) {
return dateFns.addDays(date, days);
};

// 支払期日を計算
const payDate = function(cutoffDate, terms) {
const payDateBase = addDays(cutoffDate, terms);
return latestWeekday(payDateBase);
};

// kintoneの日付フィールド向けフォーマット
const formatDate = function(date) {
return dateFns.format(date, 'YYYY-MM-DD');
};

kintone.events.on(['app.record.create.submit', 'app.record.edit.submit', 'app.record.index.edit.submit'], function(event) {
const record = event.record;
record.単純加算.value = formatDate(addDays(record.締め日.value, record.支払サイト.value));
record.支払期日.value = formatDate(payDate(record.締め日.value, record.支払サイト.value));
return event;
});

kintone.events.on(['app.record.create.show', 'app.record.edit.show', 'app.record.index.edit.show'], function(event) {
const record = event.record;
record.単純加算.disabled = record.支払期日.disabled = true;
return event;
});
})();

 

結果

2019年は、4/27〜5/6まで10連休でした。

20日後の日付がその範囲に被ると、直線の平日4/26まで戻してくれているのがわかると思います!

ライブラリについて

祝日を扱うライブラリは他にも色々ありますが、

個人的には色々な機能が盛りだくさんなライブラリよりも

「この日は祝日か否か」だけtrue/falseで返してくれれば十分なので、

holiday_jp-jsが好きなのです。

https://qiita.com/the_red/items/43c7f88ccbba001a1a95

 

moment.jsよりdate-fnsが素晴らしい理由は、

この記事にわかりやすくまとまってます。

https://www.webprofessional.jp/date-fns-javascript-date-library/

momentが予期しない挙動をして「ンガー!」ってなった経験ある方、

乗り換えてみると幸せになれるかも!

 

3

1件のコメント

Avatar
赤座 久樹

ちなみに「直後の平日」にすることも簡単にできます。

上記のコードのlatestWeekday()関数を、nextWeekday()関数として

こんな風に変更してやればOK

 

   // 直後の平日を取得
const nextWeekday = function(date) {
if (dateFns.isWeekend(date) || holiday_jp.isHoliday(date)) {
const nextDate = dateFns.addDays(date, 1);
return nextWeekday(nextDate);
}
return date;
};

 

変わってるのは実質ここだけです。

 const prevDate = dateFns.subDays(date, 1);

「1日前」じゃなくて「1日後」を計算してやればOK。

 const nextDate = dateFns.addDays(date, 1);

 

結果、こうなります!

0
ログインしてコメントを残してください。