はじめに
Notion Formula の第32回目は、「日付の間隔を○年○ヶ月○日と表示するには?」を解説します。「○年○ヶ月」までは簡単なのですが、意外と最後の○日まで出すのは大変です。この例については、こちらの逆引きで紹介しています。
数式
数式は以下のようになります。こちらも条件判断が多いので、順に式を確認していきます。
lets( /* 二つの日付の配列を作り、日付で並び替えて変数 ds に代入 */ ds, [prop("Start"), prop("End")].sort(), /* 配列の先頭(過去の日付)を取り出し、変数 st に代入*/ st, ds.first(), /* 配列の末尾(未来の日付)を取り出し、変数 et に代入*/ et, ds.last(), /* et と st の間の年数を取得し、変数 yd に代入 */ yd, et.dateBetween(st, "years"), /* et と st の間の月数を取得し、変数 md に代入 */ md, et.dateBetween(st, "months") % 12, /* yd の年数を st に追加、md の月数をさらに追加 */ yma, st.dateAdd(yd, "years").dateAdd(md, "months"), /* et と yma の間の日数を取得 */ dd, et.dateBetween(yma, "days"), (yd.empty() ? "" : yd + "年") + (md.empty() ? "" : md + "ヶ月") + (dd.empty() ? "" : dd + "日") )
境界値で場合分けしてテストするため、以下のようなデータセットを用意しました。
種別 | 開始時刻 | 終了時刻 |
---|---|---|
1日 | 2022/8/20 | 2022/8/21 |
1日(月またぎ) | 2022/7/31 | 2022/8/1 |
ちょうど一月(7/31→8/31) | 2022/7/31 | 2022/8/31 |
ちょうど一月(6/30→7/30) | 2022/6/30 | 2022/7/30 |
1月1日(6/30→7/31) | 2022/6/30 | 2022/7/31 |
ちょうど一月(5/31→6/30) | 2022/5/31 | 2022/6/30 |
1月1日(5/31→7/1) | 2022/5/31 | 2022/7/1 |
ちょうど一月(1/31→2/28) | 2022/1/31 | 2022/2/28 |
1年1月1日(1/31→3/1) | 2021/1/31 | 2022/3/1 |
1年1月1日(1/31→3/1) | 2022/3/1 | 2021/1/31 |
11ヶ月30日 | 2021/2/1 | 2022/1/31 |
11ヶ月30日 | 2022/1/31 | 2021/2/1 |
空白 |
最初は、日付範囲の開始時刻と終了時刻をそれぞれ st と et に代入します。最初にソートすることで、必ず過去の時刻が st に、未来の時刻が et に入るようになっています。
lets( /* 二つの日付の配列を作り、日付で並び替えて変数 ds に代入 */ ds, [prop("Start"), prop("End")].sort(), /* 配列の先頭(過去の日付)を取り出し、変数 st に代入*/ st, ds.first(), /* 配列の末尾(未来の日付)を取り出し、変数 et に代入*/ et, ds.last(),
種別 | ds | st | et |
---|---|---|---|
1日 | [2022/8/20, 2022/8/21] | 2022/8/20 | 2022/8/21 |
1日(月またぎ) | [2022/7/31, 2022/8/1] | 2022/7/31 | 2022/8/1 |
ちょうど一月(7/31→8/31) | [2022/7/31, 2022/8/31] | 2022/7/31 | 2022/8/31 |
ちょうど一月(6/30→7/30) | [2022/6/30, 2022/7/30] | 2022/6/30 | 2022/7/30 |
1月1日(6/30→7/31) | [2022/6/30, 2022/7/31] | 2022/6/30 | 2022/7/31 |
ちょうど一月(5/31→6/30) | [2022/5/31, 2022/6/30] | 2022/5/31 | 2022/6/30 |
1月1日(5/31→7/1) | [2022/5/31, 2022/7/1] | 2022/5/31 | 2022/7/1 |
ちょうど一月(1/31→2/28) | [2022/1/31, 2022/2/28] | 2022/1/31 | 2022/2/28 |
1年1月1日(1/31→3/1) | [2021/1/31, 2022/3/1] | 2022/1/31 | 2022/3/1 |
1年1月1日(1/31→3/1) | [2021/1/31, 2022/3/1] | 2022/1/31 | 2022/3/1 |
11ヶ月30日 | [2022/2/1, 2022/1/31] | 2021/2/1 | 2022/1/31 |
11ヶ月30日 | [2022/2/1, 2022/1/31] | 2021/2/1 | 2022/1/31 |
空白 |
yd は st と et の間の年数を取得します。これはすでに解説済みの dateBetween を使っているだけです。
/* et と st の間の年数を取得し、変数 yd に代入 */ yd, et.dateBetween(st, "years"),
種別 | st | et | yd |
---|---|---|---|
1日 | 2022/8/20 | 2022/8/21 | 0 |
1日(月またぎ) | 2022/7/31 | 2022/8/1 | 0 |
ちょうど一月(7/31→8/31) | 2022/7/31 | 2022/8/31 | 0 |
ちょうど一月(6/30→7/30) | 2022/6/30 | 2022/7/30 | 0 |
1月1日(6/30→7/31) | 2022/6/30 | 2022/7/31 | 0 |
ちょうど一月(5/31→6/30) | 2022/5/31 | 2022/6/30 | 0 |
1月1日(5/31→7/1) | 2022/5/31 | 2022/7/1 | 0 |
ちょうど一月(1/31→2/28) | 2022/1/31 | 2022/2/28 | 0 |
1年1月1日(1/31→3/1) | 2021/1/31 | 2022/3/1 | 1 |
1年1月1日(1/31→3/1) | 2021/1/31 | 2022/3/1 | 1 |
11ヶ月30日 | 2021/2/1 | 2022/1/31 | 0 |
11ヶ月30日 | 2021/2/1 | 2022/1/31 | 0 |
空白 |
md は st と et の間の月数を取得します。こちらもすでに dateBetween を使っていますが、1年を超えた場合 12 を超える値になります。月だけが欲しいので 12 の剰余を取得しています。
/* et と st の間の月数を取得し、変数 md に代入 */ md, et.dateBetween(st, "months") % 12,
種別 | st | et | dateBetween | md |
---|---|---|---|---|
1日 | 2022/8/20 | 2022/8/21 | 0 | 0 |
1日(月またぎ) | 2022/7/31 | 2022/8/1 | 0 | 0 |
ちょうど一月(7/31→8/31) | 2022/7/31 | 2022/8/31 | 0 | 1 |
ちょうど一月(6/30→7/30) | 2022/6/30 | 2022/7/30 | 0 | 1 |
1月1日(6/30→7/31) | 2022/6/30 | 2022/7/31 | 0 | 1 |
ちょうど一月(5/31→6/30) | 2022/5/31 | 2022/6/30 | 0 | 1 |
1月1日(5/31→7/1) | 2022/5/31 | 2022/7/1 | 0 | 1 |
ちょうど一月(1/31→2/28) | 2022/1/31 | 2022/2/28 | 0 | 1 |
1年1月1日(1/31→3/1) | 2021/1/31 | 2022/3/1 | 13 | 1 |
1年1月1日(1/31→3/1) | 2021/1/31 | 2022/3/1 | 13 | 1 |
11ヶ月30日 | 2021/2/1 | 2022/1/31 | 0 | 11 |
11ヶ月30日 | 2021/2/1 | 2022/1/31 | 0 | 11 |
空白 |
yma は st に yd 分の年と md 分の月を加算します。こちらは dateAdd を2回続けて実行するだけです。
/* yd の年数を st に追加、md の月数をさらに追加 */ yma, st.dateAdd(yd, "years").dateAdd(md, "months"),
種別 | st | et | dateAdd(year) | yma |
---|---|---|---|---|
1日 | 2022/8/20 | 2022/8/21 | 2022/8/20 | 2022/8/20 |
1日(月またぎ) | 2022/7/31 | 2022/8/1 | 2022/7/31 | 2022/7/31 |
ちょうど一月(7/31→8/31) | 2022/7/31 | 2022/8/31 | 2022/7/31 | 2022/8/31 |
ちょうど一月(6/30→7/30) | 2022/6/30 | 2022/7/30 | 2022/6/30 | 2022/7/30 |
1月1日(6/30→7/31) | 2022/6/30 | 2022/7/31 | 2022/6/30 | 2022/7/30 |
ちょうど一月(5/31→6/30) | 2022/5/31 | 2022/6/30 | 2022/5/31 | 2022/6/30 |
1月1日(5/31→7/1) | 2022/5/31 | 2022/7/1 | 2022/5/31 | 2022/6/30 |
ちょうど一月(1/31→2/28) | 2022/1/31 | 2022/2/28 | 2022/1/31 | 2022/2/28 |
1年1月1日(1/31→3/1) | 2021/1/31 | 2022/3/1 | 2022/1/31 | 2022/2/28 |
1年1月1日(1/31→3/1) | 2021/1/31 | 2022/3/1 | 2022/1/31 | 2022/2/28 |
11ヶ月30日 | 2021/2/1 | 2022/1/31 | 2021/2/1 | 2022/1/1 |
11ヶ月30日 | 2021/2/1 | 2022/1/31 | 2021/2/1 | 2022/1/1 |
空白 |
yma は st に yd 分の年と md 分の月を加算します。こちらは dateAdd を2回続けて実行するだけです。
/* et と yma の間の日数を取得 */ dd, et.dateBetween(yma, "days"),
種別 | yma | et | dd |
---|---|---|---|
1日 | 2022/8/20 | 2022/8/21 | 1 |
1日(月またぎ) | 2022/7/31 | 2022/8/1 | 1 |
ちょうど一月(7/31→8/31) | 2022/8/31 | 2022/8/31 | 0 |
ちょうど一月(6/30→7/30) | 2022/7/30 | 2022/7/30 | 0 |
1月1日(6/30→7/31) | 2022/7/30 | 2022/7/31 | 1 |
ちょうど一月(5/31→6/30) | 2022/6/30 | 2022/6/30 | 0 |
1月1日(5/31→7/1) | 2022/6/30 | 2022/7/1 | 1 |
ちょうど一月(1/31→2/28) | 2022/2/28 | 2022/2/28 | 0 |
1年1月1日(1/31→3/1) | 2022/2/28 | 2022/3/1 | 1 |
1年1月1日(1/31→3/1) | 2022/2/28 | 2022/3/1 | 1 |
11ヶ月30日 | 2022/1/1 | 2022/1/31 | 30 |
11ヶ月30日 | 2022/1/1 | 2022/1/31 | 30 |
空白 |
最後に yd, md, dd から文字列を作成します。空か 0 の時には単位も表示したくないので、empty() で確認し、空白に置き換えます。
(yd.empty() ? "" : yd + "年") + (md.empty() ? "" : md + "ヶ月") + (dd.empty() ? "" : dd + "日") )
種別 | yd | md | dd | 関数の結果 |
---|---|---|---|---|
1日 | 0 | 0 | 1 | 1日 |
1日(月またぎ) | 0 | 0 | 1 | 1日 |
ちょうど一月(7/31→8/31) | 0 | 1 | 0 | 1ヶ月 |
ちょうど一月(6/30→7/30) | 0 | 1 | 0 | 1ヶ月 |
1月1日(6/30→7/31) | 0 | 1 | 1 | 1ヶ月1日 |
ちょうど一月(5/31→6/30) | 0 | 1 | 0 | 1ヶ月 |
1月1日(5/31→7/1) | 0 | 1 | 1 | 1ヶ月1日 |
ちょうど一月(1/31→2/28) | 0 | 1 | 0 | 1ヶ月 |
1年1月1日(1/31→3/1) | 1 | 1 | 1 | 1年1ヶ月1日 |
1年1月1日(1/31→3/1) | 1 | 1 | 1 | 1年1ヶ月1日 |
11ヶ月30日 | 0 | 11 | 30 | 11ヶ月30日 |
11ヶ月30日 | 0 | 11 | 30 | 11ヶ月30日 |
空白 |
おわりに
今回は、「日付の間隔を○年○ヶ月○日と表示するには?」を解説しました。日付の差分を求めるために、開始時刻の○年○ヶ月後の日付を計算することで、最後の○日を計算しています。