日付の差を暦年・月・日で表すには、まず暦月を数え、次に残りの日数を数えます。このNumbersの手順では、架空の公開日と明示的な月末ルールを使うため、結果を確認できます。

たとえば、2022年5月18日から2025年9月24日までは、以下の方法で3年4か月6日となります。2月、うるう年、1月31日のような日付も扱える、再利用可能なスプレッドシートを作成します。

暦日差の意味を決める

暦日差を求めるには、開始日と、月を移動する際のルールが必要です。経過日数を365で割り、さらに30で割っても、月や年の日数は一定ではないため、暦の区切りを保てません。TC39の日付APIのドキュメントでは、より大きな単位を指定しない場合、日付の差が日数で返される理由を説明する際に、この違いを明示しています。Temporal.PlainDate documentation。

この手順では、現代のグレゴリオ暦の日付に対し、次の規則を使います。

  1. 早い日付から遅い日付へ順に進みます。
  2. 終了日を過ぎない、最大の整数月オフセットを求めます。
  3. 移動先の月に開始日と同じ日番号があればそれを使い、なければその月の末日を使います。
  4. 12か月ごとに1年とし、アンカー日から終了日までの日数を数えます。

この規則では、2025年1月31日から2月28日までは1か月です。2025年1月31日から3月30日までは1か月と30日です。2か月後のアンカーは3月31日となり、終了日を過ぎるためです。これは選んだ規則による結果であり、月の普遍的な定義ではありません。

両端の日付を含めて数えるのではなく、経過日数として数えます。そのため、同じ日付どうしの差は0年0か月0日です。期間に含まれる日付付きの暦日エントリー数を数える場合は、別の計算になります。

暦日とタイムスタンプを区別する

2025-09-24のような公開日は暦日です。つまり、暦上の年・月・日を表し、時刻や特定の瞬間は指定しません。2025-09-24T00:30:00+02:00のようなタイムスタンプには時刻とUTCからの数値オフセットが含まれ、特定の瞬間を示せます。RFC 3339では、対応する完全日付と日時の構文が定義されています。RFC 3339: Date and Time on the Internet: Timestamps。

+02:00のようなオフセットは、UTCとの関係を示します。Europe/Parisのような名前付きタイムゾーンは、瞬間と現地時刻を変換するための規則を提供し、適用されるオフセットは変わることがあります。RFC 9557では、これらの概念を区別し、オフセットだけでは現地の暦計算に必要な規則を補えない理由を説明しています。RFC 9557: Timestamps with Additional Information。

このスプレッドシートには、対象となる公開日を直接入力します。元データがタイムスタンプの場合は、まず公開日を決める名前付きタイムゾーンを選び、両方のタイムスタンプをそのタイムゾーンの日付に変換してください。例として、2025-09-24T00:30:00+02:00は2025-09-23T22:30:00Zと同じ瞬間です。基準となるタイムゾーンを決める前に表示日付を選ぶと、入力が1日ずれることがあります。

Numbersで日付差のワークシートを作成する

MacのNumbersと、AからJまでの列があり、少なくとも2行を含む表を用意します。1行目をラベル、2行目を計算に使います。以下の数式では、英語の関数名とカンマ区切りを使います。

各数式を入力するには、入力先のセルを選択し、=で始まる数式を入力または貼り付けて、Returnキーを押します。Appleの説明によると、等号を入力するとFormula Editorが開き、Functions Browserで関数のヘルプを確認できます。Calculate values using data in table cells in Numbers on Mac。

曖昧さのない開始日と終了日を入力する

A1にStart date、B1にEnd dateというラベルを付けます。次の架空の公開日を入力します。

セル 数式 入力する日付
A2 =DATE(2022,5,18) 2022年5月18日
B2 =DATE(2025,9,24) 2025年9月24日

DATE(year,month,day)を使うと、地域ごとの日付文字列の解釈の違いを避けられます。Appleは、地域設定が異なっても日付を一貫して解釈できるよう、この関数の使用を推奨しています。各月の日数が正しい、有効な暦日を指定してください。DATE。

次に進む前に、終了日が開始日と同じか、それより後であることを確認します。このワークシートは前方向の日付差を計算し、負の暦期間は定義しません。

終了日より前の最後の暦アンカーを求める

2行目に、次のラベルと数式を順に入力します。

セル 1行目のラベル 2行目の数式
C2 Candidate months =(YEAR(B2)-YEAR(A2))*12+MONTH(B2)-MONTH(A2)
D2 Complete months =C2-IF(DATE(YEAR(B2),MONTH(B2),MIN(DAY(A2),DAY(EOMONTH(B2,0))))>B2,1,0)
E2 Anchor month start =EDATE(DATE(YEAR(A2),MONTH(A2),1),D2)
F2 Anchor date =DATE(YEAR(E2),MONTH(E2),MIN(DAY(A2),DAY(EOMONTH(E2,0))))

最初の数式は、2つの日付の年月位置の差を計算します。AppleのYEAR関数とMONTH関数は、日付値からこれらの要素を取り出します。YEAR、MONTH。

2つ目の数式は、終了月のアンカーを検証します。その日番号には、開始日の日番号とその月の最終日のうち、小さい方を使います。この候補日が終了日を過ぎる場合、数式は1か月差し引きます。この条件による調整には、IFの仕様上の動作を利用します。IF。

残りの数式で実際のアンカーを作成します。EDATEは開始月の1日から計算済みのオフセット分だけ移動するため、中間段階で存在しない日付になるのを避けられます。EDATE。

次に、ワークシートで月末ルールを明示的に適用します。DAYで日番号を取り出し、EOMONTHで移動先の月の最終日を求め、MINで小さい方の日番号を選びます。これにより、月の日数が少ない場合の扱いを数式で確認できます。DAY、EOMONTH、MIN。

結果を年・月・日で表す

次の数式を入力して、ワークシートを完成させます。

セル 1行目のラベル 2行目の数式
G2 Years =QUOTIENT(D2,12)
H2 Months =MOD(D2,12)
I2 Days =DATEDIF(F2,B2,"D")
J2 Calendar difference =G2&" years, "&H2&" months, "&I2&" days"

QUOTIENTで整数除算の結果を求め、MODで余りを求めると、経過月数を年と残りの月数に変換できます。QUOTIENT、MOD。

サンプルの日付では、D2が40となり、F2は2025年9月18日を示すはずです。そのアンカーから9月24日までの6日を加えると、結果は3年4か月6日になります。簡潔にするため、テキストの数式では単数・複数の区別がない固定ラベルを使っています。年・月・日の数値は別々の列にあるため、ほかの計算にも使えます。

月末とうるう年を確認する

次の架空の日付の組み合わせを使って、ワークシートがこの規則に従っているか確認します。ほかの数式はそのままにして、A2とB2の数式だけを置き換えます。

開始日 終了日 予想される年・月・日 アンカー日
2022年5月18日 2025年9月24日 3, 4, 6 2025年9月18日
2025年1月31日 2025年2月28日 0, 1, 0 2025年2月28日
2024年1月31日 2024年2月29日 0, 1, 0 2024年2月29日
2024年2月29日 2025年2月28日 1, 0, 0 2025年2月28日
2025年1月31日 2025年3月30日 0, 1, 30 2025年2月28日
2025年9月24日 2025年9月24日 0, 0, 0 2025年9月24日

これらは、明示した規則に基づく計算例です。アンカー計算のアルゴリズムは、1万組の日付ペアを含む、決定的なPython計算で検証済みです。Numbersの画面上での実行は行っていません。

結果の経路を再構成して確認します。元の開始日から始め、D2の合計月数だけ、指定した月末ルールに沿って移動し、その後I2の日数だけ進めます。終了日に到達するはずです。月のアンカーは必ず元の開始日から計算してください。1か月ずつ繰り返し進めると、2月を経たあとに元の日番号が失われることがあります。

3つのDATEDIF結果を組み合わせない理由

Appleは、年数、年を除いた月数、月と年を除いた日数を求めるDATEDIFのオプションを説明しています。"MD"オプションは、月を置き換えて特定の日番号の計算を行います。そのため、選んだ月末調整の後に残る日数を返すものだと想定してはいけません。このワークシートでは、明示したアンカーと終了日の間に限って"D"を使います。DATEDIF。

日付APIではどのように処理するか

この計算を実装するソフトウェア向けに、TC39は日付専用の型Temporal.PlainDateと、暦を考慮した差分計算を定義しています。untilにlargestUnit: 'year'を指定すると、年とそれより小さい単位で期間が返されます。既定のオプションでは、日数による差が返されます。また、そのドキュメントでは、月の加算時に日付を範囲内に収める動作や、暦が異なる日付どうしは共通の暦に変換しない限り差分計算が拒否されることについても説明しています。Temporal.PlainDate documentation。

こうしたAPIの選択は、ワークシートの重要な決定を裏付けています。日付のみの入力を識別し、暦を選び、最大単位を指定し、月を解釈するためのアンカーを保持することです。日付文字列の規格は表記方法を定めますが、表記方法を選んだだけでは、目的に応じた月末ルールは決まりません。

予想外の結果が出たら、出力を使う前に対処する

数式でエラーが出た場合は、エラー表示を選択してメッセージを読みます。AppleのNumbersガイドでは、この診断手順を説明しています。セル参照を確認し、インストールされているNumbersが異なる区切り記号を必要とする場合は、Functions Browserを使って引数を挿入してください。Calculate values using data in table cells in Numbers on Mac。

計算結果がもっともらしく見えるのに別のツールと異なる場合は、そのツールの月末ルールをこのワークシートのルールと比較します。また、両端の日付を含めて数えていないか、暦日ではなくタイムスタンプを使っていないか、結果を丸めていないかも確認してください。逆順の日付や空欄の入力は、この前方向の計算に含めず、エラーを0に置き換えないでください。

公開日の比較に再利用する場合は、最終的な表記と一緒に開始日、終了日、アンカーを保存します。これらがそろっていれば、「3年4か月6日」のような結果を、特定の暦計算までたどって確認できます。

出典