【问题标题】:Convert Double to Datetime including milliseconds将 Double 转换为 Datetime,包括毫秒
【发布时间】:2014-05-06 13:35:26
【问题描述】:

我正在编写一个解析器,但遇到了一个我无法解决的问题。我在文本文件中有一个数字(双)734139.045000000040,它是日期。我需要将此数字转换为 DateTime 格式(yyyy-mm-dd HH:mm:ss.fff)。

我有以下代码,它给了我一个遥远的未来日期,并且肯定是错误的,我想知道我需要做什么才能获得正确的日期。不幸的是,我没有应有的 dateTime 值,我只知道这个文件是在 2010 年末或 2011 年的某个时间生成的。

我将不胜感激任何帮助或指导。

double d = double.Parse(line);
DateTime conv = DateTime.FromOADate(d);

MessageBox.Show(conv.ToString());

生成的消息框显示转换为 01/01/3910 01:04:48 请帮忙!谢谢你

【问题讨论】:

  • 这个数字代表什么?目前它只是一个数字——它是否意味着自 Unix 纪元以来的毫秒数?秒数?完全不同的东西?另请注意,DateTime 本身没有格式 - 它只是值。
  • 734139.045000000040代表什么日期?
  • @Jon Skeet & Microsft DN - 这个数字代表一个我不知道的日期,我只知道它应该在 2010 年末或 2011 年的某个地方。我可以通过试验来做不同的方法吗?错误。
  • 那么这些数据是从哪里来的?你不能问那个数据源是什么意思吗?如果你不小心的话,你很容易以微妙的错误告终。如果不知道数据的真正含义,就以特定方式解释数据绝不是一个好主意。

标签: c# visual-studio-2010 datetime type-conversion


【解决方案1】:

快速计算表明,734,139 天相当于大约 2,011 年零 4 个月。这还没有考虑闰年。那么,我怀疑 1.0 意味着一天。那么,让我们看看:

var days = 734139.045000000040;
var theDate = new DateTime(1, 1, 1).AddDays(days);
Console.WriteLine(theDate);

输出是:

2011/01/03 01:04:48

似乎有效。

我通过反复试验发现了这一点。最初的假设是该数字是从某个基值的偏移量,通常称为纪元日期。通常,偏移量是毫秒、秒或天数。我认为偏移值更可能以天表示,原因有两个:

  1. 偏移量很小。如果是秒,则为 8.5 天,如果为毫秒,则约为 12 小时。
  2. 用double 来表示毫秒数是不寻常的,用它来表示秒数几乎同样不寻常。通常你会将秒或毫秒表示为long。这并非普遍正确,但在我的经验中最为常见。

因此,我认为是天数,除以 365 进行快速估算,发现大约是 2,011 年。这与您的评论相符,即日期应该在“2010 年末或 2011 年”。

更新

如果要获取毫秒数,可以把它当成TimeSpan:

var ts = TimeSpan.FromDays(days);
var millis = ts.TotalMilliseconds;

【讨论】:

  • 谢谢你,它似乎是目前最接近的工作,我已经从来源询问了更多信息,然后可以验证,是否可以识别毫秒?
  • 我刚刚得到了更多信息,这个数字被表示为 matlab 序列号 mathworks.co.uk/help/matlab/matlab_prog/… 现在我只需要将它合并到 C# 中
  • @Rg786 您在评论中链接的页面提到 matlab 序列号 从 0000/00/00 开始。接受的答案从 0001/01/01 开始,所以如果你使用它,你会得到额外的一年(2011 年而不是 2010 年)。正如我在下面的回答中提到的,您需要从结果中减去一年才能得到正确的日期。
【解决方案2】:

如果值是“ma​​tlab 序列日期号”,就像您在其中一个 cmets 中提到的那样,请使用以下内容对其进行解析:

DateTime conv = new DateTime(1, 1, 1).AddDays(734139.045000000040).AddYears(-1)

结果:2010 年 1 月 3 日上午 1:04:48。

这会将值作为天数添加到日期 0001/01/01,然后减去一年。原因是.Net日期从0001/01/01开始,而Matlab从0000/00/00开始。

【讨论】:

    【解决方案3】:

    也许您在这里使用了错误的方法。根据有关FromOADate 的文档:

    d 参数是一个双精度浮点数,将日期表示为基准日期 1899 年 12 月 30 日午夜之前或之后的天数。d 的符号和整数部分将日期编码为正数或从 1899 年 12 月 30 日开始的负日位移,并且 d 小数部分的绝对值将一天中的时间编码为从午夜开始的一天位移的一部分。 d 必须是介于负值 657435.0 到正值 2958465.99999999 之间的值。

    这个数字实际上以毫秒为单位的可能性更大。如果这符合您的需要,那么您可以使用following DateTime constructor:

    DateTime conv = new DateTime((long)d);

    这里的d表示

    日期和时间,以自公历 0001 年 1 月 1 日 00:00:00.000 以来经过的 100 纳秒间隔数表示。

    您需要测试并告诉我们这是否适合您的需求(或不适合您的需要),以便为您提供更多有用的信息。

    【讨论】:

    • 好吧,new DateTime(); 采用 long 参数,并且 OP 试图解析的值 "734139.045000000040" 绝对不是整数。你看到那里的分数点了吗?
    猜你喜欢
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 2012-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    相关资源
    最近更新 更多