Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将Double转换为DateTime?_C#_Excel_Datetime_Datetime Format - Fatal编程技术网

C# 将Double转换为DateTime?

C# 将Double转换为DateTime?,c#,excel,datetime,datetime-format,C#,Excel,Datetime,Datetime Format,我有一个.CSV文件,我正在把它读入一个C#程序。在其中一列中,有一个日期,但它是“常规”格式,因此它在.CSV中显示为一个数字。例如:41172 如何将此数字转换为C#格式为dd/mm/yyyy的日期?41172相当于2012年9月20日。编辑:如评论和其他答案所述,这是一个更好的方法。如果这个答案不被接受,我会删除它。(但是,仍然有一些像.NET Core这样的平台不支持FromOADate,因此它仍然对使用这些平台的人有用。) 我怀疑你想要: DateTime date = new Dat

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


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

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

我怀疑你想要:

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

(有关为什么需要减去2的原因,请参见其他答案。)

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

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


要从“Excel格式”的日期时间转换为C#日期时间,可以使用该函数

在您上面的示例中:

   DateTime myDate = DateTime.FromOADate(41172);
要以所需格式将其写出以供显示,请使用:

   myDate.ToString("dd/MM/yyyy");
如果您想知道Excel数据处理中的差异来自何处,那么应该是故意的:

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

当MicrosoftMultiplan和MicrosoftExcel发布时,它们也 假设1900年是闰年。这使得微软可以进行多重规划 和Microsoft Excel使用与Lotus相同的串行数据系统 1-2-3,并提供与Lotus 1-2-3更大的兼容性。治疗 1900年是闰年,这也使得用户更容易移动工作表 从一个程序到另一个程序

虽然技术上可以纠正这种行为,以便 当前版本的Microsoft Excel并不认为1900是一个飞跃 今年,这样做的弊大于利

资料来源:

我从MSDN:中看到了这一点,但我实际上认为这是错误的

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

要检查这一点,请尝试将Excel中的单元格格式化为日期,然后输入
1
,它将给出
1 1900年1月
。现在输入
59
,它将给出
1900年2月28日
<代码>60给出了
1900年2月29日
(不是真实日期),然后
61
给出了
1900年3月01日

所以

开关(天)
{
案例<1:
//无效。做任何事。。。
打破
例<59:
DateTime日期=新的日期时间(1900,1,1).AddDays(天);
打破
违约:
//取消1900年2月29日和2000年2月29日造成的额外天数
DateTime日期=新的日期时间(1900,1,1)。添加天数(天-2);
打破
}

如果您正在.Net Core中查找
FromOADate
,则它不在那里

我分解了.Net框架的实现,并创建了一个扩展方法

        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;
        }
publicstaticdatetime FromOADate(此双日期)
{
返回新的日期时间(DoubleDateToTicks(date),DateTimeKind.Unspecified);
}
内部静态长DoubleDateToTicks(双值)
{
如果(值>=2958466.0 | |值=0.0?0.5:-0.5));
如果(num1<0升)
num1-=num1%86400000L*2L;
长num2=num1+59926435200000L;
如果(num2<0L | | num2>=315537897600000L)
抛出新ArgumentException(“不是有效值”);
返回num2*10000L;
}

仍然需要测试。

我同意asp.net中没有我知道的日期格式!这只是一个随机数!您必须尝试将有效日期导出到CSV文件。什么程序正在创建CSV文件?DateTime.FromOADate(41172)是否适合您“基准日期之前或之后的天数,1899年12月30日午夜”,谣言是:因为1900年不是闰年,但有人忘记了。它似乎是一致的,所以我可以减去2。非常感谢。@HenkHolterman我听说的故事是为了保持与Lotus 1-2-3的兼容性,Lotus 1-2-3最初存在此错误。@Paul:如果您不接受此答案,则接受另一个答案(例如dash),我将删除此答案。2000年是闰年。就像1600年和2400年一样。所以你在1900年左右才对。@Henk:谢谢!我确实知道这一点,但不知怎么忘了。哈哈,我是个白痴!我将编辑我的答案……这里有另一个关于同样特质的有趣轶事:
        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;
        }