Excel 中日期,其实存储的是数字,如下:
可以看出:
数字 1 代表 1900-01-01。
数字 0 代表 1900-01-00 就有点没意思了。
数字 60 代表 1900-02-29 就是一种错误了,因为 1900 年并不是闰年。
据说:最早是 Lotus 有这个 BUG,微软为了与之兼容,也是这么干的。
所以咱们利用程序取 Excel 日期时间时,取得的小数,要转换,可以这么转换:
var d = DecimalValue; int i = (int)d; // 整数部分。 var m = Math.Abs(d - (int)d); // 小数部分。0.5 表示 12 点、0.75 表示 18 点。 // 1 对应 1900-1-1。 // 60 对应 1900-2-29,错误日期,因为 1900 年并不是闰年,这是 Excel 的 BUG。 // 61 对应 1900-3-1,AddDays 减 2,因为有 1900-2-29 这个干扰。 // 86400 = 3600 * 24,小数部分对应的时间。 if (i >= 61) { // 注意 AddDays 减 2,因为有 1900-2-29 这个干扰。 return new DateTime(1900, 1, 1).AddDays(i - 2).AddSeconds((double)(86400 * m)); } else if (i >= 60) { throw new Exception("错误日期:1900-2-29"); } else if (i >= 1) { // 注意 AddDays 减 1。 return new DateTime(1900, 1, 1).AddDays(i - 1).AddSeconds((double)(86400 * m)); } else if (i >= 0) { // Excel 认为存在 1900-1-0 这一天。 throw new Exception("错误日期:1900-1-0"); } else { // Excel 都不认这个日期了。 throw new Exception("错误日期"); }