将Double转换为DateTime?

时间:2012-08-15 11:35:30

标签: c# excel datetime datetime-format

我有一个.CSV文件,我正在阅读C#程序。在其中一列中,有一个日期,但它采用“通用”格式,因此它在.CSV中显示为数字。例如:41172。

如何在C#中将此数字转换为格式为dd / mm / yyyy的日期? 41172相当于20/09/2012。

5 个答案:

答案 0 :(得分:31)

要从“Excel格式”中的日期时间转到C#日期时间,您可以使用DateTime.FromOADate功能。

在上面的示例中:

   DateTime myDate = DateTime.FromOADate(41172);

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

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

如果您想知道Excel日期处理中的差异来自何处,那么它应该是故意的:

  

当Lotus 1-2-3首次发布时,该程序假定为年份   1900年是闰年,尽管它实际上不是闰年。这个   使程序更容易处理闰年并且没有造成任何伤害   几乎所有在Lotus 1-2-3中的日期计算。

     

当Microsoft Multiplan和Microsoft Excel发布时,他们也是   假设1900年是闰年。这允许Microsoft Multiplan   和Microsoft Excel使用Lotus使用的相同的序列日期系统   1-2-3并提供与Lotus 1-2-3更好的兼容性。治疗   1900年作为闰年也使用户更容易移动工作表   从一个程序到另一个程序。

     

虽然技术上可以纠正这种行为   当前版本的Microsoft Excel并不认为1900是一个飞跃   一年,这样做的缺点超过了优势。

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

答案 1 :(得分:14)

编辑:正如评论和其他答案所述,DateTime.FromOADate是一种更好的方法。如果它没有被接受,我会删除这个答案。 (但是,仍有像.NET Core这样的平台,FromOADate不受支持,所以它对使用这些平台的人来说仍然有用。)

我怀疑你想要:

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

(请参阅其他答案,了解为什么需要减去2。)

答案 2 :(得分:3)

如果你在.Net Core中寻找FromOADate,它就不存在了。

我解释了实现.Net Framework并创建了一个扩展方法。

        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;
        }

仍然需要测试它。

答案 3 :(得分:2)

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

  

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

答案 4 :(得分:-1)

我在MSDN上看过这个:http://msdn.microsoft.com/en-us/library/system.datetime.fromoadate.aspx,但我认为这是错误的。

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

要检查这一点,请尝试将Excel中的单元格格式化为日期,然后输入1并提供1 Jan 1900。现在输入59,它会28 Feb 190060提供29 Feb 1900(不是真实日期),然后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;
}