奇怪的纪元日期编号问题

时间:2016-03-10 18:30:43

标签: c# date unix-timestamp alternate

我正在处理一个数据集,其中有一个日期字段,其日期如下所示:

  

42437.4261290278
  42437.5460402431
  42437.5478825116

数字中较大的一个是最近的。我们中的一个人认为它与unix时代和交替时间表示有关。我们现在面临的问题是将上述日期读入标准MM-DD-YYYY格式。任何人对如何将这些备用日期表格转换为标准日期有任何想法吗?

我正在尝试在C#中执行此操作。作为参考,我预计最后两个日期将在2016年3月8日的某个时间列出,并且在此之前是第一个。

2 个答案:

答案 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"));