LuxonはMoment.jsの後継的なライブラリにあたり、日付を処理できます。
この記事では、kintoneカスタマイズにおけるLuxonの導入方法や、日時フォーマットの変更などのよくある日付処理をLuxonで扱う方法を紹介します。
Luxonは日付データのフォーマット、バリデーション、計算、表示するためのJavaScriptライブラリです。
ソースコードは
GitHub
にあり、
公式ドキュメント
も公開されています。
Moment.jsとの違い
固定リンクがコピーされました
メリット1:Luxon単体でタイムゾーンを扱える
Moment.jsでタイムゾーンに関する操作を扱う場合、
Moment Timezone
というライブラリの追加が必要でした。
参考:
Moment Timezoneを使って簡単時差管理
Luxonは単体でタイムゾーンに対する操作ができます。
1
2
luxon.DateTime.local().setZone('America/New_York' ).toISO();
// 2020-05-21T00:09:04.124-04:00
メリット2:Luxonで生成するオブジェクトはイミュータブルなオブジェクト
イミュータブルなオブジェクトとは、作成した後に状態が変わらないオブジェクトのことです。
Moment.jsのオブジェクトはミュータブルなため(イミュータブルではないため)、日付の加算などの操作をすると操作元のオブジェクトも変更されます。
1
2
3
4
5
6
7
8
const date = moment();
const oneDayLater = date.add(1 , 'days' ); // 元のオブジェクトに対して操作する
console.log('date:' + date.format('YYYY-MM-DD' ));
console.log('oneDayLater:' + oneDayLater.format('YYYY-MM-DD' ));
// 元のオブジェクト(date)も、1日後の日付に変更されている
// date: 2020-05-22
// oneDayLater: 2020-05-22
Moment.jsで元のオブジェクトに影響させたくない場合は、オブジェクトを複製し、複製したオブジェクトに対して操作する必要がありました。
1
2
3
4
5
6
7
8
const date = moment();
const oneDayLater = date.clone().add(1 , 'days' ); // 複製したオブジェクトに対して操作する
console.log('date:' + date.format('YYYY-MM-DD' ));
console.log('oneDayLater:' + oneDayLater.format('YYYY-MM-DD' ));
// 元のオブジェクト(date)は、元の日付のまま
// date: 2020-05-21
// oneDayLater: 2020-05-22
Luxonはイミュータブルなオブジェクトのため、日付の加算などを行っても、元のオブジェクトが変更されることはありません。
1
2
3
4
5
6
7
8
const date = luxon.DateTime.local();
const oneDayLater = date.plus({days: 1 });
console.log('date:' + date.toFormat('yyyy-MM-dd' ));
console.log('oneDayLater:' + oneDayLater.toFormat('yyyy-MM-dd' ));
// 元のオブジェクト(date)は、元の日付のまま
// date: 2020-05-21
// oneDayLater: 2020-05-22
注意点:ブラウザーによっては利用できない機能がある
固定リンクがコピーされました
Luxonは主要ブラウザーのメジャーバージョンの2世代前までを公式にサポートしています。
詳細は公式サイト> Support matrixの
Official support
を参照してください。
kintoneカスタマイズでの導入方法
固定リンクがコピーされました
次のURLをkintoneの「JavaScript / CSSでカスタマイズ」画面から指定し、その後にカスタマイズファイルを指定します。
https://js.cybozu.com/luxon/3.0.4/luxon.min.js
上記URLは、2022年10月3日時点でのCybozu CDNで配信されている最新バージョンのURLです。
Luxonを導入する際は、
Cybozu CDN
を確認し、必要に応じて配信されているバージョンを変更してください。
CDNを読み込むと、グローバルオブジェクトとしてluxonが追加されています。
これを使って、Luxonオブジェクトを生成してみましょう。
1
2
3
4
5
6
7
8
// 現在日時から生成
const currentDate = luxon.DateTime.local();
// kintoneの日時フィールドの値から生成(フィールドコードが「日時」)
const dateFieldCode = '日時' ;
const record = kintone.app.record.get().record;
const dateFieldValue = record[dateFieldCode].value;
const dateFieldDate = luxon.DateTime.fromISO(dateFieldValue);
いろいろな書式の文字列を取得してみましょう。
その他の書式については、公式サイト>
Formatting
をご参考ください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Luxonオブジェクトを生成
const date = luxon.DateTime.local();
// yyyy-MM-dd形式
// 例: 2020-06-02
date.toFormat('yyyy-MM-dd' );
// 年月のみ(0埋めなし)
// 例: 2020年6月
date.toFormat('yyyy年M月' );
// 曜日
// 例: 火曜日
date.setLocale('ja' ).toFormat('EEEE' );
// 時刻フィールドの書式
// 例: 09:00
date.toFormat('HH:mm' );
// 日時フィールドの書式
// 例: 2020-06-02T15:00:00.000+09:00
date.toISO();
x日後や月初などの日付を操作してみましょう。
その他の操作については、公式サイト>
Math
をご参考ください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Luxonオブジェクトを生成
const date = luxon.DateTime.local();
// 3日後
const threeDaysLater = date.plus({days: 3 });
// 月初
const startOfMonth = date.startOf('month' );
// 月末
const endOfMonth = date.endOf('month' );
// その週の月曜日
const mondayOfTheWeek = date.set({weekday: 1 });
kintoneカスタマイズでの実用例
固定リンクがコピーされました
cybozu developer networkのTipsで紹介している日付計算を、Luxonを使って実装してみましょう。
年齢や経過年数を計算する
経過年数を表示する
では、生年月日フィールドから年齢の計算や、入社年月日フィールドから入社してからの経過年月を計算しています。
これらの計算をLuxonを使って行ってみましょう。
カスタマイズを適用するアプリには、以下のフィールドがあるものとします。
フィールド名
フィールドの種類
フィールドコード
生年月日
日付
BirthDay
入社年月日
日付
JoiningDay
サンプルコードでは、アプリのレコードの詳細画面を開いたときに、年齢や入社してからの経過年月を開発者ツールのコンソールに表示します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/*
* Luxon sample program
* Copyright (c) 2020 Cybozu
*
* Licensed under the MIT License
* https://opensource.org/license/mit/
*/
(() => {
'use strict' ;
kintone.events.on('app.record.detail.show' , (event) => {
const record = event.record;
const birthDayFieldCode = 'BirthDay' ;
const joiningDayFieldCode = 'JoiningDay' ;
/**
* 経過年月日を計算する
* @param {string} dateStr 日付文字列
* @returns {object} 計算結果のオブジェクト
*/
const calculateDuration = function (dateStr) {
const currentDate = luxon.DateTime.local().startOf('day' );
const date = luxon.DateTime.fromISO(dateStr).startOf('day' );
// 経過期間を計算する
const duration = currentDate.diff(date, ['years' , 'months' , 'days' ]);
return duration.toObject();
};
// 年齢を計算する
const birthDayValue = record[birthDayFieldCode].value;
const birthDayDuration = calculateDuration(birthDayValue);
console.log(birthDayDuration.years + '歳' );
// 入社からの経過年月を計算する
const joiningDayValue = record[joiningDayFieldCode].value;
const joiningDayDuration = calculateDuration(joiningDayValue);
console.log(joiningDayDuration.years + '年' + joiningDayDuration.months + 'ヶ月' );
return event;
});
})();
期限を過ぎているかを計算する
ログインユーザーが担当しているレコードに背景色をつける
では、期限フィールドの値を使って、「期限が過ぎているか」や「期限のn
日前を過ぎているか」を計算しています。
これらの計算をLuxonを使って行ってみましょう。
カスタマイズを適用するアプリには、以下のフィールドがあるものとします。
フィールド名
フィールドの種類
フィールドコード
期限
日付
LimitDay
サンプルコードでは、アプリのレコード一覧画面を開いたとき、それぞれのレコードが期限を過ぎていた場合や期限の5日前を過ぎていた場合に、開発者ツールのコンソールに表示します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/*
* Luxon sample program
* Copyright (c) 2020 Cybozu
*
* Licensed under the MIT License
* https://opensource.org/license/mit/
*/
(() => {
'use strict' ;
kintone.events.on('app.record.index.show' , (event) => {
const DAYS = 5 ;
const records = event.records;
const idFieldCode = '$id' ;
const limitDayFieldCode = 'LimitDay' ;
/**
* 期限のx日前か
* @param {string} dateStr 日付文字列
* @param {number} days x日
* @returns {boolean} 期限のx日前ならtrue
*/
const isBeforeDeadline = function (dateStr, days) {
const date = luxon.DateTime.fromISO(dateStr).startOf('day' );
// 今日からx日後の日付オブジェクト
const addedDate = luxon.DateTime.local().plus({days: days}).startOf('day' );
return date <= addedDate;
};
/**
* 期限を過ぎているか
* @param {string} dateStr 日付文字列
* @returns {boolean} 期限が過ぎていればtrue
*/
const isExpired = function (dateStr) {
const date = luxon.DateTime.fromISO(dateStr).startOf('day' );
const currentDate = luxon.DateTime.local().startOf('day' );
return date < currentDate;
};
records.forEach((record) => {
const limitDayValue = record[limitDayFieldCode].value;
const idValue = record[idFieldCode].value;
if (isExpired(limitDayValue)) {
console.log('レコード番号' + idValue + 'は、期限を過ぎています' );
} else if (isBeforeDeadline(limitDayValue, DAYS)) {
console.log('レコード番号' + idValue + 'は、期限の' + DAYS + '日前を過ぎています' );
}
});
return event;
});
})();
LuxonやMoment.jsといった日付処理ライブラリを使うと、JavaScriptのDate型では面倒な日付処理を楽に扱うことができます。
kintoneカスタマイズで日付処理をしたいときには、ぜひこちらもご参考ください。
またMoment.jsからLuxonに移行する際には、公式サイトの
For Moment users
をご参考ください。