EL式を利用して、日付・日時を出力(代入)する際の設定書式です。[データ更新]の日付型/日時型データ項目への代入や、[タイマー中間イベント]の日時設定など、各工程で日付・日時の値をセットする際に利用されます。
このページのサンプルは、いずれも「① どの日付・日時を基準にするか」と「② その基準をどう加工するか(○分後・翌月末など)」の組み合わせでできています。まず基準(固定値/ケース開始日時/システム時刻/データ項目/文字列)を選び、必要に応じて .addDays() などのメソッドで加工する、という読み方をすると、やりたいことをどの書式で書けばよいか探しやすくなります。
BPMNアイコン:[データ更新]、[タイマー中間イベント]、など
1. 指定フォーマットで固定の日付/日時を入力する
あらかじめ決まった特定の日付・日時を、そのまま代入したいときに使います。固定値を入れるときは、時分を含めず、代入先の型・サブタイプの書式そのもので書きます。
| 設定書式(入力例) | 対象の型・サブタイプ | 代入された結果 |
|---|---|---|
| 2020-03-14 23:45 | 日時型 | 2020-03-14 23:45 |
| 日付型(年月日) | 2020-03-14 | |
| 2020-03 | 日付型(年月) | 2020-03 |
| 03-14 | 日付型(月日) | 03-14 |
| 2020 | 日付型(年) | 2020 |
未指定の部分は内部で既定値に補完されます(『月日』は年を 2000 年、『年』は 1 月 1 日として扱う)。表示は各サブタイプの書式になります。
2. ケース開始日時を基準にする
processInstanceStartDatetime は、そのケースが開始された日時を表します。「申請日の3日後」「開始月の月末」など、ケースの起点からの相対的な日付・日時を求めたいときに使います。
| 設定書式 | 何をしているか | 日付型の結果 | 日時型の結果 |
|---|---|---|---|
| processInstanceStartDatetime | ケース開始日時そのもの | 2020-03-14 | 2020-03-14 23:45 |
| processInstanceStartDatetime.addMinutes(30) | 30分後 | 2020-03-15 | 2020-03-15 00:15 |
| processInstanceStartDatetime.addHours(2) | 2時間後 | 2020-03-15 | 2020-03-15 01:45 |
| processInstanceStartDatetime.addDays(3) | 3日後 | 2020-03-17 | 2020-03-17 23:45 |
| processInstanceStartDatetime.addMonths(-4) | 4か月前 | 2019-11-14 | 2019-11-14 23:45 |
| processInstanceStartDatetime.addDays(#q_num?.intValue()) ※ | 数値型データ項目に入っている日数だけ後 | 2020-03-17 ※ | 2020-03-17 23:45 ※ |
| processInstanceStartDatetime.addMonths(1).getFirstTimeInMonth() | 翌月の初日 0:00(=翌月1日) | 2020-04-01 | 2020-04-01 00:00 |
| processInstanceStartDatetime.addMonths(1).getLastTimeInMonth() | 翌月の末日 23:59(=月末締め) | 2020-04-30 | 2020-04-30 23:59 |
| processInstanceStartDatetime.getFirstTimeInWeek() | その週の月曜 0:00(週は月曜日始まり) | 2020-03-09 | 2020-03-09 00:00 |
| processInstanceStartDatetime.addDays(1).getFirstTimeInDate().addHours(9) | 翌日の 0:00 にそろえてから9時間後(=翌日 9:00) | 2020-03-15 | 2020-03-15 09:00 |
※ 固定の数値の代わりに、数値型データ項目(q_num)の値が参照されます。.intValue() は値を整数として扱うための指定です。
加工メソッドの読み方:.addMinutes()/.addHours()/.addDays()/.addMonths() は指定分だけ先の日時にずらします(マイナス値で過去方向)。.getFirstTimeInWeek()/.getFirstTimeInMonth()/.getLastTimeInMonth() は週初(月曜)・月初・月末に、.getFirstTimeInDate() はその日の 0:00 にそろえます。これらを繋げて「翌月末の9時」などを表現できます。
3. 実行時の日付(#today)を基準にする
#today は、式が評価された瞬間(実行時)の日付を表します。時刻は 0:00 に切り捨てられます。ケース開始日時と違い、その工程が実行されるたびの「今日」を使いたいときに用います。
| 設定書式 | 何をしているか | 日付型の結果 | 日時型の結果 |
|---|---|---|---|
| #today | 当日(0:00) | 2020-06-20 | 2020-06-20 00:00 |
| #today.addMonths(1) | 1か月後の同日(0:00) | 2020-07-20 | 2020-07-20 00:00 |
| #today.addDays(5) | 5日後 | 2020-06-25 | 2020-06-25 00:00 |
| #today.getFirstDateInWeek().addDays(1) | その週の火曜(月曜+1日) | 2020-06-16 | 2020-06-16 00:00 |
| #today.getFirstDateInMonth().addDays(2) | その月の3日(1日+2日) | 2020-06-03 | 2020-06-03 00:00 |
| #today.getLastDateInMonth().addDays(-1) | その月の末日の前日(末日−1日) | 2020-06-29 | 2020-06-29 00:00 |
4. 実行時の日時(#now)を基準にする
#now は、式が評価された瞬間(実行時)の日時を、時分まで含めて表します。工程が実行される「今」を時刻込みで使いたいときに用います。
| 設定書式 | 何をしているか | 日付型の結果 | 日時型の結果 |
|---|---|---|---|
| #now | 現在の日時 | 2020-06-20 | 2020-06-20 14:30 |
| #now.addDays(-7) | 7日前の同時刻 | 2020-06-13 | 2020-06-13 14:30 |
| #now.getFirstTimeInDate().addHours(33) | 翌日の 9:00(0:00 の 33 時間後) | 2020-06-21 | 2020-06-21 09:00 |
| #now.getFirstTimeInWeek().addDays(2) | その週の水曜 0:00(月曜+2日) | 2020-06-17 | 2020-06-17 00:00 |
| #now.getFirstTimeInMonth() | その月の初日 0:00 | 2020-06-01 | 2020-06-01 00:00 |
| #now.getLastTimeInMonth() | その月の末日 23:59 | 2020-06-30 | 2020-06-30 23:59 |
#today は「日付だけで良い(時刻は 0:00)」とき、#now は「時分まで必要」なときに使い分けます。
5. 日時型データ項目を基準にする
フォームで入力された日時(日時型データ項目)を基準に加工します。項目名の前に # を付けて参照します。データ項目は空(null)の場合があるため、メソッドを呼ぶときはセーフナビゲーション演算子 ?. を使います(例:#q_datetime?.addHours(9))。基準が空のときは結果も空(クリア)になります。
(以下は「q_datetime」に 2020-04-15(水)09:00 が入っている場合の例)
| 設定書式 | 何をしているか | 日付型の結果 | 日時型の結果 |
|---|---|---|---|
| #q_datetime | 日時型データ項目「q_datetime」の値 | 2020-04-15 | 2020-04-15 09:00 |
| #q_datetime?.addHours(9) | その9時間後 | 2020-04-15 | 2020-04-15 18:00 |
| #q_datetime?.getFirstTimeInWeek()?.addDays(3) | その週の木曜 0:00(月曜+3日) | 2020-04-16 | 2020-04-16 00:00 |
| #q_datetime?.getFirstTimeInMonth()?.addDays(9) | その月の10日 0:00(1日+9日) | 2020-04-10 | 2020-04-10 00:00 |
| #q_datetime?.getLastTimeInMonth()?.addDays(-3) | その月の末日の3日前 23:59(末日−3日) | 2020-04-27 | 2020-04-27 23:59 |
6. 日付型データ項目を基準にする
フォームで入力された日付(日付型データ項目)を基準に加工します。項目名の前に # を付けて参照し、空(null)に備えて ?. を使います。日付型のまま加工するメソッドは、結果も日付型(時分なし)になります。
(以下は「q_date」に 2020-04-15(水)が入っている場合の例)
| 設定書式 | 何をしているか | 日付型の結果 |
|---|---|---|
| #q_date?.addDays(3) | 3日後 | 2020-04-18 |
| #q_date?.addMonths(2) | 2か月後 | 2020-06-15 |
| #q_date?.getFirstDateInWeek() | その週の月曜(週は月曜日始まり) | 2020-04-13 |
| #q_date?.getFirstDateInMonth() | その月の初日(1日) | 2020-04-01 |
| #q_date?.getLastDateInMonth() | その月の末日 | 2020-04-30 |
日付型を日時型に変換して時刻を足す
日付型には時刻を足すメソッド(.addHours() など)は用意されていません。「その日の特定の時刻」を作りたいときは、まず .getFirstTimeInDate() で日時型(その日の 0:00)に変換してから .addHours() などで時分を加えます。
| 設定書式 | 何をしているか | 日時型に代入された結果 |
|---|---|---|
| #q_date?.getFirstTimeInDate()?.addHours(9) | 日付型「q_date」を日時型(0:00)に変換して当日 9:00 | 2020-04-15 09:00 |
| #q_date?.getFirstTimeInDate()?.addHours(33) | 日付型「q_date」の翌日 9:00(0:00 の 33 時間後) | 2020-04-16 09:00 |
(例:「希望日」の日付型項目から「希望日の午前9時に送るリマインド時刻」という日時型の値を作る、など)
7. 文字列から変換する
#dateFormatter.parse(...) は、指定した書式の文字列を日付・日時に変換します。§1 の固定リテラルで書けるものには不要で、日付型データ項目の値を組み替えて別の日付を作りたいときに使います。
| 設定書式 | 何をしているか | 日付型の結果 | 日時型の結果 |
|---|---|---|---|
| #dateFormatter.parse('yyyy-MM-dd', '2021-' + #q_md) | 月日型「q_md」(04-01) に年(2021) を補って日付に変換 | 2021-04-01 | 2021-04-01 00:00 |
8. 条件に応じた日付の選択(三項演算子)
EL式では 条件式 ? 真の場合の値 : 偽の場合の値 という三項演算子が使えます。日付型・日時型データ項目への代入でも利用でき、2つの日時のうち早い(または遅い)方を選ぶ用途などに応用できます。比較演算子は < <= == != >= > が使えます。&&(かつ)や入れ子の三項演算子と組み合わせれば、3つ以上の中から選ぶこともできます。
| 設定書式 | 代入される結果(例) |
|---|---|
| #q_date1 < #q_date2 ? #q_date1 : #q_date2 | 「q_date1」と「q_date2」のうち、早い方の日付 |
| #q_datetime1 < #now ? #now : #q_datetime1 | 「q_datetime1」が過去なら現在日時、そうでなければ「q_datetime1」 |
| #q_date1 >= #q_date2 && #q_date1 >= #q_date3 ? #q_date1?.addDays(7) : (#q_date2 >= #q_date3 ? #q_date2?.addDays(7) : #q_date3?.addDays(7)) | 「q_date1〜q_date3」のうち最も遅い日付の7日後 |
※ 比較する日付・日時項目のどちらかが空(null)のときは、例外にはなりませんが結果も空(null)になります。SpEL では null は最小値(nothing)として扱われるため、「空でない方が選ばれる」わけではない点に注意してください(空の項目を除いて選びたい場合は、#q_date1 == null などの明示的な null チェックを組み合わせます)。
9. 式だけでは扱えないこと
以下は「データ更新」の EL 式だけでは実現できません。スクリプトタスクや外部連携など、別の手段が必要です。
- 営業日・祝日を考慮した計算(「3営業日後」「翌営業日」など)。Questetra BPM Suite は祝日・営業日カレンダーのデータを持たないため、式だけでは判定できません(曜日は算出できますが、祝日は判定できません)。
- タイムゾーンをまたぐ変換(UTC ↔ ローカル時刻など)。日付・日時は基盤のタイムゾーンで解釈されるため、式の中でオフセットや夏時間を扱うことはできません。
Notes
- 『日付型(年月日)』と『日時型』は相互変換(代入)が可能です。例) 「日付型:2020-03-14」=>「日時型:2020-03-14 00:00」、「日時型:2020-03-14 23:45」=>「日付型:2020-03-14」
- 『日付型』は(『日時型』と異なり)「23:45」等の時分情報を持ちません。『締切』に応用した場合は当該日の「23:59」として、『タイマー中間』に応用した場合は当該日の「00:00」として動作します。
- [データ更新]では、設定書式として何も設定しない場合、「空」が代入されます(データが消去されます)。
- 日付・日時は、ワークフロー基盤のタイムゾーン(例:JST +09:00)に従って解釈されます。
- 使えるメソッドは型によって異なります。日付型には時刻を足す
.addMinutes()/.addHours()は使えず、日時型には日付型専用の.getFirstDateInWeek()/.getFirstDateInMonth()/.getLastDateInMonth()は使えません(存在しないメソッドの呼び出しはエラーになります)。