我正在处理一个数据集,其中有一个日期字段,其日期如下所示:
42437.4261290278
42437.5460402431
42437.5478825116
数字中较大的一个是最近的。我们中的一个人认为它与unix时代和交替时间表示有关。我们现在面临的问题是将上述日期读入标准MM-DD-YYYY格式。任何人对如何将这些备用日期表格转换为标准日期有任何想法吗?
我正在尝试在C#中执行此操作。作为参考,我预计最后两个日期将在2016年3月8日的某个时间列出,并且在此之前是第一个。
答案 0 :(得分:6)
这些是OLE自动化VT_DATE值。这是Microsoft产品(如Excel和Visual Basic的.NET前版本)使用的日期系统。这是一种有点奇怪的日期格式。
格式为:考虑double有两部分:有符号整数和无符号分数。有符号整数是自1899年12月30日以来的天数。注意不是1899年12月31日而是1900年1月1日。分数是24小时(总是!)一天的分数。我们每年有两次23或25小时的天数没有调整。
这种格式有一个有趣的(对我来说)历史;你可以在我2003年的博客文章中看到它:
https://blogs.msdn.microsoft.com/ericlippert/2003/09/16/erics-complete-guide-to-vt_date/
Stack Overflow创始人Joel Spolsky的文章来自2006年:
http://www.joelonsoftware.com/items/2006/06/16.html
请注意,如果您有负 VT_DATE值,那么您必须非常小心才能使转换正确。代码并不难;它只是几行,但你必须仔细推理它。我曾经问过“将两个VT_DATE之间的差异作为一个面试问题”,并且令人惊讶的候选人实际上不能进行减法。
答案 1 :(得分:1)
在你断言所代表的日期是2016-03-08之后,我认为这个时代的开始是1899-12-30:
static string UnixTimeStampToDateAsString(double ts)
{
DateTime epoch = new DateTime(1899, 12, 30);
DateTime d = epoch.AddDays(ts);
return (d.ToString("yyyy-MM-dd HH:mm:ss"));
}
static void Main(string[] args)
{
foreach (double dateNumber in new double[] { 42437.4261290278, 42437.5460402431, 42437.5478825116 })
{
Console.WriteLine(UnixTimeStampToDateAsString(dateNumber));
}
Console.ReadLine();
}
输出:
2016-03-08 10:13:37
2016-03-08 13:06:17
2016-03-08 13:08:57
我必须指出,1899年12月30日是一个相当不太可能的价值,但我想有人可能有“理由”使用它。
编辑感谢@EricLippert我可以建议:
Console.WriteLine(DateTime.FromOADate(dateNumber).ToString("yyyy-MM-dd HH:mm:ss"));