インクリメンタルなカイハツにっき

.NET 開発手法を中心に、これから始める方の一助となる記事を載せていく予定です。

Excel に潜む1900年問題

Microsoft Excel を使い続けて、20年近く経つ今日この頃。
今更ながら知った事実が...

ことの発端というか、やりたかったことは、プログラム(C#)から数値を設定して、Excelからはその数値を参照して、日付を取得する処理。
...と文章に書くと、よく意味わかりませんが、例えば「A1」セルに数値を設定すると、そのセルを参照している「B1」セルに日付が表示される...とするとわかるでしょうか。
実際はそんな単純なものではないけれど。

Excel で数値を日付で表示する

まぁこんな感じで...

Excelで数値を日付で表示

基本知識として、Excel ではセルの表示形式を「日付」とすると、数値を日付に直して表示してくれます。
「1」を日付表示とすると、「1900/1/1」、「2」だと「1900/1/2」となります。

...と考えた場合、今日の日付を数値として取得する場合、C#で書くと...

(DateTime.Today - new DateTime(1900, 1, 1)).Days + 1;

「今日」から「1900/1/1」を差となる日数に1を足す。
こんな感じでいけるはずです。

「今日」はちょっと不確定要素なんで、「2016/2/8」を数値とすると...

var result = (new DateTime(2016, 2, 8) - new DateTime(1900, 1, 1)).Days + 1;

この result の値を、EPPlus を利用して特定のセルに設定し、作業を進めていたのですが...

どーもおかしい!
なんか、日付がずれてる。

と思い、この result を日付で表現してみると...

2016/2/7?なんでやねん!

あっれ~コードは間違えようがないしなー
「1」入れたら、ちゃんと「1900/1/1」やし。間違ってないわな...
1900年...ん?1900年!1900年は特別な年やん!

と思い、
『え~っと。31+29は60か。ほんじゃ60入れてみたら...』

そこに表示されたのは、予想通り。あるはずのない
1900/2/29

存在しない19000229

1900年2月29日は存在しない?

...ここでうるう年についておさらい。
西暦が4で割り切れる年はうるう年となり、2月が29日までになります。
「誰でも知っとるわ!」というツッコミは軽くスルーして、そう考えると、4で割り切れる1900年は当然うるう年のはず...

というのは引っ掛け(?)で、うるう年には更にルールがあり、
100で割り切れる年はうるう年とはならない
へー。でも、確か2000年はうるう年だった気が...ともうひとつ。
400で割り切れる年はうるう年
ということで、2000年問題とか騒いでたあの年は、まさに異例の年だったわけですね。

まぁ詳しくはこちらで。
閏年 - Wikipedia

というわけで、話を戻すと、1900年の2月29日は存在しないわけですね。
そりゃ、ずれるわ。

既知の有名な問題

ちなみにこの問題、検索かけてみるといっぱい Hit しました。有名な話なんですね...
わかってるけど今更直せない。そんな感じなんでしょうか。

https://support.microsoft.com/ja-jp/kb/214326

まぁ仕方ないんでコードを変えましょう。

var result = (new DateTime(2016, 2, 8) - new DateTime(1900, 1, 1)).Days + 2;

今更ながら、ひとつ賢くなりました。