将Double转换为DateTime?

我有一个.CSV文件,我正在读入一个C#程序。 在其中一列中,有一个date,但是它是“一般”格式,所以在.CSV中显示为一个数字。 例如:41172。

我怎样才能将这个数字转换为格式dd / mm / yyyy在C#中的date? 41172相当于20/09/2012。

编辑:如注释和其他答案中所述, DateTime.FromOADate是一个更好的方法。 我会删除这个答案,如果它是不被接受的。 (但是,仍然有像.NET Core这样的平台,其中FromOADate不受支持,因此对于使用这些平台的用户来说仍然是有用的。)

我怀疑你想要:

 DateTime date = new DateTime(1900, 1, 1).AddDays(days - 2); 

(请参阅其他答案为什么你需要减去2)

要从“Excel格式”中的DateTime转到C#date时间,可以使用DateTime.FromOADate函数。

在你上面的例子中:

  DateTime myDate = DateTime.FromOADate(41172); 

要将其写出来以所需格式显示,请使用:

  myDate.ToString("dd/MM/yyyy"); 

如果您想知道Exceldate处理中的差异来自哪里,则应该是有意的:

当Lotus 1-2-3首次发布时,该计划假设1900年是一个闰年,即使它实际上不是一个闰年。 这使得程序更容易处理闰年,并且几乎不会影响Lotus 1-2-3中的所有date计算。

当Microsoft Multiplan和Microsoft Excel发布时,他们也认为1900年是一个闰年。 这使得Microsoft Multiplan和Microsoft Excel能够使用Lotus 1-2-3所使用的相同的序列date系统,并且与Lotus 1-2-3提供了更好的兼容性。 1900年作为一个闰年,也使用户更容易将工作表从一个程序移动到另一个程序。

尽pipe在技术上可以纠正这种行为,以便当前版本的Microsoft Excel不会假设1900年是闰年,但这样做的缺点大于优点。

资料来源: http : //www.ozgrid.com/Excel/ExcelDateandTimes.htm

Excel使用的date格式是旧的,但DateTime.FromOADate函数仍然支持该函数,您可以使用该函数来转换此数字。 它被定义为

基准date之前或之后的天数,1899年12月30日午夜

如果你正在寻找在.Net核心FromOADate它不在那里。

我分解了.Net Framework的实现,并创build了一个扩展方法。

  public static DateTime FromOADate(this double date) { return new DateTime(DoubleDateToTicks(date), DateTimeKind.Unspecified); } internal static long DoubleDateToTicks(double value) { if (value >= 2958466.0 || value <= -657435.0) throw new ArgumentException("Not a valid value"); long num1 = (long)(value * 86400000.0 + (value >= 0.0 ? 0.5 : -0.5)); if (num1 < 0L) num1 -= num1 % 86400000L * 2L; long num2 = num1 + 59926435200000L; if (num2 < 0L || num2 >= 315537897600000L) throw new ArgumentException("Not a valid value"); return num2 * 10000L; } 

仍然需要testing它。

我已经从MSDN看到这个: http : //msdn.microsoft.com/en-us/library/system.datetime.fromoadate.aspx ,但我实际上认为这是错的。

真正的问题是,Excel错误地认为,世纪年(1900年)是一个闰年,而实际上并不是,而是2000年!

要检查这一点,尝试在Excel中格式化一个单元格作为date,然后input1 ,它会给1 Jan 1900 。 现在input59并且在28 Feb 190060给出29 Feb 1900 (不是真正的date),然后61给出01 March 1900

所以…

 switch (days) { case < 1: // Not valid. Do whatever... break; case < 59: DateTime date = new DateTime(1900, 1, 1).AddDays(days); break; default: // Knock off the extra days caused by 29 Feb 1900 and 29 Feb 2000 DateTime date = new DateTime(1900, 1, 1).AddDays(days-2); break; }