0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

相続の法定期限をD1で扱う:起算点は「死亡日」ではないという設計上の落とし穴

0
Last updated at Posted at 2026-08-29

環境・前提条件

  • TypeScript: 5.4.5
  • Node.js: 20.12.2
  • Wrangler: 3.53.1
  • Cloudflare D1(SQLite互換エンジン)
  • date-fns: 3.6.0

この記事の要点

  • 法定期限の起算点は「事実が起きた日」ではなく「知った日」です。死亡日から計算すると全期限がずれます。
  • 起算点は期限ごとに違います。3か月と10か月は相続開始を知った日、3年は所有権の取得を知った日が起点です。
  • 施行前にさかのぼる経過措置は相対計算で表せません。日付定数として持ち、根拠を併記します。

相続手続きの複数の法定期限を、D1でどうデータモデル化するか?

起算日となる日付を物理保持し、各法定期限はクエリまたは関数側で導出します。ただし起算日は1つではありません。ここを1本にまとめると、全期限が同じ幅だけずれます。

最初に作ったスキーマは date_of_death(死亡日)だけを持ち、3か月・10か月・3年をすべてそこから計算していました。動作はしますが、法律上は誤りです。

  • 相続放棄の熟慮期間(3か月)… 自己のために相続の開始があったことを知った時から(民法915条1項)
  • 相続税の申告・納付(10か月)… 相続の開始があったことを知った日の翌日から(相続税法27条1項)
  • 相続登記の申請義務(3年)… 所有権を取得したことを知った日から(不動産登記法76条の2第1項)

疎遠な親族の相続では、死亡から数か月後に通知で知ることが珍しくありません。死亡日を起点にすると、実際にはまだ数か月残っている案件を「期限切れ」と表示します。逆に、遺産分割の成立で初めて所有権を取得した不動産では、死亡日起点は期限を早く見積もりすぎます。

CREATE TABLE inheritance_cases (
    id TEXT PRIMARY KEY,
    deceased_name TEXT NOT NULL,
    date_of_death TEXT NOT NULL,  -- 相続開始日。事実の記録であり、期限の起算日ではない
    date_known TEXT NOT NULL,     -- 自己のために相続の開始があったことを知った日
    created_at TEXT DEFAULT (DATETIME('now'))
);

CREATE TABLE inheritance_properties (
    id TEXT PRIMARY KEY,
    case_id TEXT NOT NULL REFERENCES inheritance_cases(id),
    property_type TEXT NOT NULL CHECK (property_type IN ('land', 'building', 'condo')),
    address TEXT NOT NULL,
    -- 所有権の取得を知った日。遺産分割で確定する場合、date_known より後になる
    date_acquisition_known TEXT NOT NULL,
    registration_status TEXT DEFAULT 'pending'
        CHECK (registration_status IN ('pending', 'completed')),
    registered_at TEXT
);

date_known を NOT NULL にしているのは、値が無いときに死亡日で代用させないためです。NULL 許容にすると COALESCE(date_known, date_of_death) を書きたくなり、そこから誤りが戻ります。分からない場合は入力の時点で確認する、という運用に倒します。

SQLiteの日付関数仕様は公式ドキュメント( https://www.sqlite.org/lang_datefunc.html )を参照しています。

月末日や閏年が絡む相対日付計算を、TypeScriptでどう安全に行うか?

date-fnsaddMonths / addYears を使い、月ごとの日数差と閏年による繰り上がりを解決します。

民法143条1項は「週、月又は年によって期間を定めたときは、その期間は、暦に従って計算する」と定めます。応当する日が無い月の扱いは同条2項ただし書で、「月又は年によって期間を定めた場合において、最後の月に応当する日がないときは、その月の末日に満了する」とされています。JavaScript標準の DatesetMonth(getMonth() + 3) を実行すると、1月31日は3月3日(閏年なら3月2日)へ繰り越されます。date-fns は末日へ丸めるため、この規定と一致します。

import { addMonths, addYears, format, isBefore, max, parseISO } from 'date-fns';

/** 相続登記義務化の施行日(改正不動産登記法)。 */
const ENFORCEMENT_DATE = parseISO('2024-04-01');

/**
 * 施行前に開始した相続の登記期限。
 *
 * 施行日から3年という経過措置だが、法務省の案内では2027年3月31日とされている。
 * addYears(施行日, 3) は 2027-04-01 を返すため、計算結果とは1日ずれる。
 * 初日不算入(民法140条)の扱いによる差なので、**計算せず公表値を定数で持つ**。
 * 出典: 法務省「相続登記の申請義務化について」
 */
const TRANSITION_DEADLINE = '2027-03-31';

export interface DeadlineInput {
  /** 自己のために相続の開始があったことを知った日 */
  dateKnown: string;
  /** 所有権を取得したことを知った日(物件ごと) */
  dateAcquisitionKnown: string;
}

export interface InheritanceDeadlines {
  renunciationDeadline: string;  // 相続放棄・限定承認(3か月)
  taxFilingDeadline: string;     // 相続税の申告・納付(10か月)
  registrationDeadline: string;  // 相続登記(3年/経過措置あり)
}

export function calculateDeadlines(input: DeadlineInput): InheritanceDeadlines {
  const known = parseISO(input.dateKnown);
  const acquired = parseISO(input.dateAcquisitionKnown);

  // 施行前に取得を知った場合は経過措置。施行後なら知った日から3年。
  const registration = isBefore(acquired, ENFORCEMENT_DATE)
    ? TRANSITION_DEADLINE
    : format(addYears(acquired, 3), 'yyyy-MM-dd');

  return {
    // 「知った時から3か月」。初日不算入と応当日前日満了が相殺し、知った日+3か月に一致する
    renunciationDeadline: format(addMonths(known, 3), 'yyyy-MM-dd'),
    // 「知った日の翌日から10か月」。翌日起算が明示されているため、知った日+10か月に一致する
    taxFilingDeadline: format(addMonths(known, 10), 'yyyy-MM-dd'),
    registrationDeadline: registration,
  };
}

経過措置を max(施行日, 取得を知った日) の相対計算で表そうとして、公表値と1日ずれました。制度側が日付を名指ししている場合は、計算で再現しようとせず定数で持つのが安全です。ずれても例外は出ず、期限表示が1日長くなるだけなので、テストが無ければ気づけません。

関数仕様の詳細は date-fns 公式ドキュメント( https://date-fns.org/docs/addMonths )に準拠しています。

登記が未完了のレコードを、D1で高速に抽出するには?

未登記ステータスと起算日の複合インデックスを定義し、期限が近い案件を絞り込みます。経過措置があるため、期限はCASE式で分岐させます。

CREATE INDEX idx_properties_status
    ON inheritance_properties(registration_status, date_acquisition_known);

-- 登記期限まで90日を切った未登記物件
SELECT
    p.id AS property_id,
    p.address,
    CASE
        WHEN p.date_acquisition_known < '2024-04-01' THEN '2027-03-31'
        ELSE date(p.date_acquisition_known, '+3 years')
    END AS registration_deadline
FROM inheritance_properties p
WHERE p.registration_status = 'pending'
  AND CASE
        WHEN p.date_acquisition_known < '2024-04-01' THEN '2027-03-31'
        ELSE date(p.date_acquisition_known, '+3 years')
      END <= date('now', '+90 days')
ORDER BY registration_deadline ASC;

CASE式をWHERE句に書くとインデックスが効きません。件数が増えたら、期限を生成列(GENERATED ALWAYS AS ... STORED)として保持し、そこにインデックスを張る形へ移します。派生値を持たない原則より、誤りなく速く引けることを優先する判断です。ただし生成列にすると経過措置の定数がスキーマに焼き付くため、制度改正時の移行手順を残しておく必要があります。

Cloudflare D1のインデックス設計は公式ドキュメント( https://developers.cloudflare.com/d1/platform/client-api/ )に基づきます。

法定期間の根拠

相続放棄(3か月)は民法915条1項、相続税の申告・納付(10か月)は相続税法27条1項および国税庁「No.4205 相続税の申告と納税」、相続登記の申請義務(3年・2024年4月1日施行)は不動産登記法76条の2第1項、施行前の相続に関する経過措置(2027年3月31日)は法務省「相続登記の申請義務化について」に基づきます。

本記事のコードは実装例であり、個別の期限判断は司法書士・税理士にご確認ください。

この記事は株式会社HY(横浜・湘南/不動産・相続)の社内システム開発の記録です。


訂正(2026-09-03): 公開時、期間計算の根拠を「民法143条2項」と書いていましたが、「暦に従って計算する」は同条1項です。2項は応当日・末日の規定でした。該当箇所を条文の原文に差し替えています。ご指摘をいただく前の自主点検で見つけたものです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?