ブログ一覧に戻る
給与計算日割り計算中途入社中途退社労務

中途入退社の日割り計算、月末の 1 日でズレる罠 — niyase が確認した 26 のケース

はじめに

給与計算で 地味だけど絶対に間違えてはいけない 領域があります。

中途入退社の日割り計算です。

毎月の基本給は、まるまる 1 ヶ月在籍した従業員にはそのまま支給します。問題は、月途中で入社した人、月途中で退社した人、そして両方が同じ月に起きるレアケースです。

「20 日入社で、月給 30 万円。今月の給与はいくらにする?」

この問いに、給与計算ソフトはどう答えるかで、お客様の従業員の生活が左右されます。本記事では、niyase が日割り計算をどう実装したか、そして検証で確認した 26 ケースをご紹介します。

「日割り」と一口に言っても、複数の方式がある

まず、日割りには大きく分けて以下の選択肢があります。

方式計算式特徴
暦日基準月給 × (在籍日数 ÷ 月の暦日数)2 月は 28 日、1 月は 31 日で割る
営業日基準月給 × (在籍営業日数 ÷ 月の営業日数)土日祝を除いて計算
所定労働日基準月給 × (在籍所定労働日数 ÷ 月の所定労働日数)会社カレンダーで定めた所定日のみ

niyase では 暦日基準 をデフォルトとしています。月給の支給単位 (= 「1 ヶ月という単位」) に対応する考え方として、最もシンプルで予想しやすいためです。会社の規程によって他の方式が指定されているお客様には、設定で切替可能な構造にしています。

よくある「うっかり間違える」5 つのパターン

パターン 1: 月の日数違いを忘れる

2 月入社の月給 30 万円の従業員と、3 月入社の同条件の従業員。両方とも「20 日入社」だった場合、初月給与は同じになるでしょうか。

  • 2 月 (28 日) で 20 日に入社 → 在籍日数 9 日 → 9/28 × 30 万円 = 96,428 円
  • 3 月 (31 日) で 20 日に入社 → 在籍日数 12 日 → 12/31 × 30 万円 = 116,129 円

同じ「20 日入社」でも、月の日数で結果がかなり違います。「自社の規程の式」と「ソフトの計算結果」が、月によって違って見える原因はこれです。

パターン 2: 月初入社 (= 1 日入社) は日割りなし

「3 月 1 日入社」の場合、その月は 満額 の月給を支給するのが一般的です。日割り係数は 1.0 (= 全額)。

これを「3 月 1 日入社 → 3 月の在籍 31 日 / 月の暦日 31 日 = 100%」と計算すれば結果は同じですが、「1 日入社だから日割りしない」と「1 日入社の日割り係数は 1.0」が、コードの分岐として違って見えるとバグの温床になります。

niyase では「日割り係数 = min(在籍日数, 月の暦日数) ÷ 月の暦日数」という統一式にして、入社日や退社日に関わらず同じ式が走るようにしました。

パターン 3: 月末退社 (= 月の末日退社) は満額

「3 月 31 日退社」の場合、その月は満額。3 月 30 日退社なら 30/31。

「末日退社」と「最終日退社」の表現はそれぞれの会社の規程で扱いが違うので、niyase では「退社日まで在籍とみなす」(退社日も日数に含める) を採用しています。

パターン 4: 同月内の入社 → 退社

非常に稀ですが、例えば 3 月 10 日入社 → 3 月 25 日退社、というケース。

  • 在籍日数 = 25 - 10 + 1 = 16 日 (両端を含む)
  • 日割り係数 = 16 / 31

niyase では入社日も退社日も両方在籍日数に含めるルールにしているため、上記の式がそのまま使えます。

パターン 5: 入社月と退社月が違う場合の中間月

入社月と退社月の 間の月 は、当然満額です。

「2 月 15 日入社、4 月 20 日退社」の従業員の 3 月給与は、3 月まるまる在籍なので満額。これは日割り計算ロジックに「月単位の判定」を入れて、対象月が在籍期間に完全に含まれているなら係数 1.0 を返す、という分岐です。

niyase の実装方針 — 純粋関数として切り出し

これらの計算ロジックを、niyase では 純粋関数 として共通パッケージに切り出しました。

function calculateProration({
  joinDate, // 入社日 (なければ undefined = 期初から在籍)
  leaveDate, // 退社日 (なければ undefined = 期末まで在籍)
  periodStart, // 給与計算期間の開始日 (e.g. 2026/03/01)
  periodEnd, // 給与計算期間の終了日 (e.g. 2026/03/31)
}): ProrationResult;

この関数は、入社日 / 退社日 / 計算期間 の組み合わせを入力として、日割り係数 (0.0〜1.0) と在籍日数を返します。給与計算サービス側では、この係数を基本給などに掛け算するだけで日割りが完了します。

Vitest で 26 ケースを通す

純粋関数として切り出したことで、テストが書きやすくなりました。実装時には以下の 26 ケースをテストとして用意しました。

月の日数違い (4 ケース)

  • 28 日月 (2 月、うるう年なし)
  • 29 日月 (2 月、うるう年)
  • 30 日月 (4 月 / 6 月 / 9 月 / 11 月)
  • 31 日月 (1 月 / 3 月 / 5 月 / 7 月 / 8 月 / 10 月 / 12 月)

入社パターン (7 ケース)

  • 月初 (1 日) 入社 → 日割りなし
  • 月途中入社 (5 日 / 15 日 / 25 日)
  • 月末 (末日) 入社 → 1 日分
  • 期初前入社 (前月以前) → 満額
  • 期末後入社 (翌月以降) → 0

退社パターン (7 ケース)

  • 月初 (1 日) 退社 → 1 日分
  • 月途中退社 (10 日 / 20 日)
  • 月末 (末日) 退社 → 満額
  • 期末後退社 (翌月以降) → 満額
  • 期初前退社 (前月以前) → 0

入退社が同月のケース (4 ケース)

  • 月初入社 + 月末退社 → 満額
  • 月途中入社 + 月途中退社
  • 同日入退社 (極稀)
  • 入社日 > 退社日 (データ不整合、エラー扱い)

計算期間ずれ (4 ケース)

  • 計算期間が 1 ヶ月より長い (補正期間)
  • 計算期間が 1 ヶ月より短い (締日変更月など)
  • 入社日が計算期間外
  • 退社日が計算期間外

すべてのケースで期待値どおりの結果が返ることを CI で継続的に検証しています。テストケース数を訴求するつもりはなく、「こういう罠があるとわかっているから、漏れがないように網羅している」という姿勢の現れだと思っていただければ。

おわりに

中途入退社の日割り計算は、給与計算の中でも「事故が起きると従業員から信頼を失う」領域です。1 円ズレるだけで「うちの会社の給与計算は大丈夫か」と疑念が生まれます。

niyase クラウド (認証取得を準備中) では、上記のロジックがバックエンドで自動適用されます。お客様側で「うちの会社の場合、日割りはどうするんだっけ?」と毎月考える必要のない作りにしています。

派手な機能ではありません。でも、お客様の従業員 1 人ひとりの信頼が積み上がる場所だと考えて、地味に作り込んでいます。