奇怪的纪元日期编号问题
strange epoch date number issue
我正在处理一个数据集,其中有一个日期字段,其日期如下所示:
42437.4261290278
42437.5460402431
42437.5478825116
其中较大的数字是最新的。我们中的一个人认为它与 unix 纪元和交替时间表示有关。我们现在面临的问题是将上述日期读入标准的 MM-DD-YYYY 格式。有人对如何将这些备用日期格式转换为标准日期有任何想法吗?
我正尝试在 C# 中执行此操作。作为参考,我希望列出的最后两个日期是 2016 年 3 月 8 日的某个时间,第一个是在此之前的某个时间。
根据您断言表示的日期是 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 日是一个不太可能的值,但我想可能有人 "reason" 可以使用它。
编辑 感谢@EricLippert 我可以建议改为:
Console.WriteLine(DateTime.FromOADate(dateNumber).ToString("yyyy-MM-dd HH:mm:ss"));
这些是 OLE 自动化 VT_DATE 值。这是 Microsoft 产品(例如 Excel 和 Visual Basic 的 .NET 之前版本)使用的日期系统。这是一种有点奇怪的日期格式。
格式为:考虑双精度数有两部分:有符号整数和无符号小数。带符号的整数是自 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 值,那么您必须非常小心才能正确转换。代码并不难;这只是几行,但你必须仔细推理。我曾经问过 "take the difference between two VT_DATEs" 作为面试题,而且很多候选人实际上不会做减法。
我正在处理一个数据集,其中有一个日期字段,其日期如下所示:
42437.4261290278
42437.5460402431
42437.5478825116
其中较大的数字是最新的。我们中的一个人认为它与 unix 纪元和交替时间表示有关。我们现在面临的问题是将上述日期读入标准的 MM-DD-YYYY 格式。有人对如何将这些备用日期格式转换为标准日期有任何想法吗?
我正尝试在 C# 中执行此操作。作为参考,我希望列出的最后两个日期是 2016 年 3 月 8 日的某个时间,第一个是在此之前的某个时间。
根据您断言表示的日期是 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 日是一个不太可能的值,但我想可能有人 "reason" 可以使用它。
编辑 感谢@EricLippert 我可以建议改为:
Console.WriteLine(DateTime.FromOADate(dateNumber).ToString("yyyy-MM-dd HH:mm:ss"));
这些是 OLE 自动化 VT_DATE 值。这是 Microsoft 产品(例如 Excel 和 Visual Basic 的 .NET 之前版本)使用的日期系统。这是一种有点奇怪的日期格式。
格式为:考虑双精度数有两部分:有符号整数和无符号小数。带符号的整数是自 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 值,那么您必须非常小心才能正确转换。代码并不难;这只是几行,但你必须仔细推理。我曾经问过 "take the difference between two VT_DATEs" 作为面试题,而且很多候选人实际上不会做减法。