11

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

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

4

5 回答 5

33

要从“Excel 格式”的 DateTime 转换为 C# Date Time,您可以使用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

于 2012-08-15T11:53:58.377 回答
15

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

我怀疑你想要:

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

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

于 2012-08-15T11:42:47.160 回答
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;
        }

还是需要测试一下。

于 2017-04-26T06:49:57.727 回答
2

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

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

于 2012-08-15T11:52:36.713 回答
-1

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

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

要检查这一点,请尝试将 Excel 中的单元格格式化为日期,然后输入1并给出1 Jan 1900. 现在输入59,它给出了28 Feb 1900. 60给出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;
}
于 2012-08-15T11:54:49.757 回答