Excelの日付が「46317」のような数字になる理由と、ほかのツールに渡すときに日付を壊さない方法

Kwangmo Yang·公開日

Excelの日付が急に数字で表示されたり、別のファイルにコピーしたら4年ずれたりするのは、日付の正体が「シリアル値」という数値だからです。Microsoftの公式ドキュメントをもとに、仕組みと、CSVやPythonに渡すときの注意点を整理しました。

この記事が答える問い

Excelで管理している売上表や顧客リストを、別のツールに取り込んだり、プログラムで読み込んだりしたとき、日付の列が「46317」のような数字になってしまうことがあります。別のブックにコピーしたら、日付がちょうど4年ずれていた、という相談もよく聞きます。

どちらも、Excelの日付の正体を知っていれば原因が分かります。この記事では、Microsoftの公式ドキュメントをもとに仕組みを整理し、ほかのツールに日付を渡すときに壊さない方法をまとめます。

結論

  • Excelの日付は、内部では**「シリアル値」という数値**で記録されている。日付に見えるのは表示形式のおかげ
  • 日付が4年(正確には1,462日)ずれるのは、1900年日付システムと1904年日付システムが混ざったとき
  • プログラムでシリアル値を日付に戻すときは、1899年12月30日を起点にすると、1900年3月1日以降の日付が正しく変換できる
  • ほかのツールに渡すときは、「YYYY-MM-DD」の文字列にしておくのがいちばん安全

Excelの日付の正体は「シリアル値」

Microsoftのドキュメントによると、Excelに日付を入力すると、日付は**開始日から経過した日数を表す数値(シリアル値)**に変換されます。たとえば「2011年7月5日」は、シリアル値40729として記録されます。

画面に「2011/7/5」と表示されるのは、セルに日付の表示形式が付いているからです。表示形式が外れたり、表示形式の情報を持たないツールに値だけが渡されたりすると、中身の数値がそのまま見えます。記事タイトルの「46317」は、この記事を書いた2026年10月22日のシリアル値です。

時刻も同じ仕組みです。TIMEVALUE関数の説明では、時刻は0から0.99988426までの小数で表され、0:00:00から23:59:59までを表すとされています。つまり「46317.5」は、2026年10月22日の12時です。

日付が4年ずれる理由:2つの日付システム

Excelには、1900年日付システムと1904年日付システムの2つがあります。

日付システム開始日2011年7月5日のシリアル値
1900年日付システム1900年1月1日40729
1904年日付システム1904年1月1日39267

ドキュメントでは、新しいバージョンのExcelはすべて1900年日付システムで日付を計算し、古いバージョンのExcel for Macでは1904年日付システムが使われていたと説明されています。2つの差は**1,462日(4年と1日)**です。

同じ数値でも、どちらのシステムで読むかで日付が4年と1日ずれます。古いMacで作られたブックのデータを扱うときや、日付が「ちょうど4年ずれている」ときは、まずこの設定を疑います。設定は、Windows版ではブックごとに[ファイル]→[オプション]→[詳細設定]の「1904年日付システムを使用する」で確認できます。

なお、ドキュメントでは、別のブックへ日付をコピーするときは通常は自動で変換される一方、グラフの一部としてコピーされた日付は変換されず、約4年ずれるため手動で直す必要がある、とも書かれています。

なぜ起点が「1899年12月30日」なのか

1900年日付システムの開始日は1900年1月1日なので、起点は1899年12月31日のように思えます。ところが、プログラムで変換するときは1899年12月30日を起点にするのが一般的です。

理由は、Excelが1900年を閏年として扱っているためです。Microsoftのドキュメントによると、これは当時の表計算ソフトLotus 1-2-3との互換性のためで、実際には存在しない1900年2月29日がExcelには存在します。そのぶん、1900年3月1日以降の日付は1日ずれているため、起点を1日前に置くと計算が合います。

実際に、Pythonで1899年12月30日に40729日を足すと、ドキュメントの例と同じ2011年7月5日になります。

from datetime import datetime, timedelta

def excel_serial_to_datetime(serial: float) -> datetime:
    # 1900年日付システム、1900年3月1日以降の日付が前提
    return datetime(1899, 12, 30) + timedelta(days=serial)

print(excel_serial_to_datetime(40729))    # 2011-07-05 00:00:00
print(excel_serial_to_datetime(46317.5))  # 2026-10-22 12:00:00

pandasを使う場合は、to_datetime の unit と origin を指定します。

import pandas as pd

pd.to_datetime([40729, 46317.5], unit="D", origin="1899-12-30")
# DatetimeIndex(['2011-07-05 00:00:00', '2026-10-22 12:00:00'], ...)

どちらのコードも、手元で実行して結果を確認しています。1904年日付システムのブックから来た値なら、起点を1904年1月1日にする必要があります。

ほかのツールに日付を渡すときのルール

シリアル値は、Excelの中では便利ですが、ほかのツールとの受け渡しでは誤解のもとになります。受け渡しのルールとして、次の点を決めておくと安全です。

  • 日付は「YYYY-MM-DD」の文字列で渡す:数値のまま渡すと、受け取る側が起点や日付システムを知っている必要がある
  • 時刻が必要なら「YYYY-MM-DD HH:MM:SS」で、タイムゾーンも決める:小数部分の時刻は、見た目では気づきにくい
  • 受け取ったデータに5桁の数字の日付があったら、シリアル値を疑う:4万台の数字なら、2009年〜2036年ごろの日付の可能性が高い
  • 日付が4年ずれていたら、1904年日付システムを疑う

Excel側で文字列にするなら、TEXT関数で =TEXT(A2,"yyyy-mm-dd") のように表示形式を指定して変換できます。

チェックリスト

  1. 日付の列に、5桁の数字が混ざっていないか
  2. 日付が4年ずれていないか(1904年日付システムのブックが混ざっていないか)
  3. プログラムで変換するとき、起点を1899年12月30日にしているか
  4. 時刻を含む値の小数部分を、切り捨てていないか
  5. 受け渡しの形式を「YYYY-MM-DD」の文字列に決めているか

まとめ

Excelの日付が数字になるのは、壊れたのではなく、中身のシリアル値が見えているだけです。日付が4年ずれるのも、日付システムの違いという理由があります。

仕組みが分かれば、対処は難しくありません。Excelの中ではシリアル値、外に出すときは「YYYY-MM-DD」の文字列。この切り替えを受け渡しのルールとして決めておくと、日付のトラブルはほとんど防げます。

参考資料

  1. 1Excel の日付システム|Microsoft サポート
  2. 2Excel では、1900 年が閏年であると誤って想定しています|Microsoft Learn
  3. 3TIMEVALUE 関数|Microsoft サポート
  4. 4pandas.to_datetime|pandas documentation

Kwangmo Yang

Freelance Developer & Translator · Based in Osaka, Japan

大阪を拠点に、AI業務自動化、Web・ツール開発、日韓の言語サービスを手がけています。

プロフィールを見る

Contact

効率化への新しい一歩、 一緒に踏み出しませんか

プロジェクトをお持ちですか?お気軽にご連絡ください。

お問い合わせ

関連記事