C#からExcelファイルを開いて、日付が入っているセルの値を取りたいとき。
シリアル値が取れてしまうので、これをDateTimeに変換するときにハマった話。
セルの値を取得する部分は多くの解説サイトさんがあるので、そちら参照。
取得したRange型オブジェクト.Value値を文字列として取得したと仮定して話を進めます。
if (double.TryParse(取得値, out double serial))
{
// 時刻はいらないので削ぎ落とす
int dateCount = (int)serial;
// Excelの標準日時でDateTimeを初期化
DateTime dateFromTick = new DateTime(1900, 1, 1);
// 1 = 1900/1/1なので、1引いた日数を加算
return dateFromTick.AddDays(dateCount - 1);
}
これが1日ずれる件。
色々探してたら、Excelでは1900年だけ閏年とみなす処理がされているらしいです。
うわ、本当だ。
1900年は閏年ではないのに、2/29が作れてしまう…。
2/29のシリアル値である60を上回っていたらズレ始めている、ということなので1減算します。
if (double.TryParse(取得値, out double serial))
{
// 時刻はいらないので削ぎ落とす
int dateCount = (int)serial;
// Excelでは1900年を閏年として処理しているので、2/29を含んでいたら1引いておく
if (60 <= dateCount)
{
dateCount--;
}
// Excelの標準日時でDateTimeを初期化
DateTime dateFromTick = new DateTime(1900, 1, 1);
// 1 = 1900/1/1なので、1引いた日数を加算
return dateFromTick.AddDays(dateCount - 1);
}
他にもニッチなIT関連要素をまとめていますので、よければ一覧記事もご覧ください。