Edited at

Excelの日付データは1900年1月1日から数えた連番ではない 1900年うるう年問題

More than 1 year has passed since last update.

Excelの日付データは1900年3月1日を61とした連番である( ー`дー´)キリッ


百聞は一見にしかず:rolling_eyes:

画像はExcel2013


ざっくりいうと

Excelが日付1900/02/29を認めていて1900年が閏年になるバグ仕様がある

グレゴリオ暦では1900年は閏年ではない

マイクロソフトの公式サポートにも嘘が書いてある:thinking::thinking::thinking:

https://support.office.com/ja-jp/article/aaa2159b-4ae8-4651-8bce-d4707bc9fb9f

引用


Microsoft Office Excel では、日付を計算するために、日付が一連のシリアル値として格納されます。たとえば、Microsoft Office Excel for Windows では、1900 年 1 月 1 日はシリアル値 1 となり、2008 年 1 月 1 日はシリアル値 39448 となります (これは、1900 年 1 月 1 日から 39,448 日が経過しているためです)。



日付計算ツールなどで調べたら

参考 http://keisan.casio.jp/exec/system/1177658154

1900/1/1~2008/1/1までは39447日:smirk:


つまりどういうことだってばよ:poop:

Excelは日付をシリアル値という数値で管理していて

1900/1/1を[1]として

1900/1/2 → [2]

1900/1/3 → [3]

というようになっている。しかし残念なことに

1900/2/28 → [59]

1900/2/29 → [60]

1900/3/1  → [61]

になっていて1900年2月29日にもシリアル値があてがわれている・・・

手元のExcel2013で確認(最新のExcelだと直ってるかどうか知らない)


調べてみた


2100年は?問題なし(2100/2/29は存在しない)

ふむ・・・:thinking:


グレゴリオ暦を認識してないわけではなくて1900年だけ起きる

ふむふむ・・・:thinking::thinking:


原因は?

Excel開発時の都合によりそうなっていて互換性の問題で根強く残った仕様とのこと

なるほどなるほど・・・(ノ)・ω・(ヾ)

Microsoftがそう言うんなら文句言っても仕方ない。仕様なのだろう:worried:

(Excel2016 - Office365ではどうなのかコメントで教えて欲しい)


関数の処理は?

画像参照Excel2013で確認



不幸なことに関数もこのバグ仕様を認識していないご様子

何日経過したか調べる時に1900/2/29をまたぐときに注意すべきである。

1900/2/28~1900/3/1は1日しか差がないはずが引き算では2になる

幸いなことに1900/3/1以降は正常に動作する:hugging:


曜日は?

wikipediaによると


現行のグレゴリオ暦は、1582年10月15日に、この日を金曜日であるとして施行された


とのことなので計算すると1900/1/1は月曜日であるべきだ。ツェラーの公式などからも導ける

しかしセルに(aaaa)で曜日を適用すると・・・



1900/1/0~1900/2/29まで曜日がずれている。

どうもこのバグ仕様を認識した上で1900/3/1(木)以降は正常に動作するようになってるようだ。:hugging:


余談 ことの発端

CSVでデータのやり取りをするシステムの話

クライアントから依頼

『CSVをExcelで編集したけどそうするとたまに日付が「43160」(=2018/03/01)とかになって困る。これでも日付として認識して欲しい』

とのこと

うんまぁ実はExcel的には見た目の問題なのでセルの表示形式から日付を選んでもらえばいいよなぁ:thinking:

と思いつつ

しかし、こういう問い合わせはITに詳しくない人から際限なく来る

問い合わせのたびにExcelで日付形式には注意してから保存してくださいねと伝えるのも馬鹿らしい

じゃあシステムで丸めるように対応しておくか・・・?

たしか日付は1900年1月1日から連番だったよな?



数値を日付差として認識すればいいから1900/1/1にDATE型で足し算すればいいな



実装



なんか日付が1日ずれてるんですけど:smiling_imp:



(´・ω・`)


ちなみにMicrosoft Visual Basicだと

http://www.openreference.org/articles/view/212

CDate(-1) → 1899/12/29

CDate( 0) → 00:00:00

CDate( 1) → 1899/12/31

CDate( 2) → 1900/01/01

となっておりCDate関数でExcelのバグ仕様とシリアル値が1900年3月1日以降で一致する。

2を1/1に設定するわけないし故意ではなかろうか:thinking:


閑話休題

Excel日付は1900年1月1日を「1」として数えた連番ではなくて

1900年3月1日を「61」とした連番であると認識すると良い

これで世界が一つ平和になった:grinning:

てゆうか

1900年うるう年問題よりも

1899年以前の日付が認識できていないことの方が問題なきが・・・