什么是Java中的DateTime.FromOADate()(Java中的日期时间为double)

时间:2014-05-15 06:11:37

标签: c# java .net datetime

C#DateTime.FromOADate()方法。

Java 中的DateTime.FromOADate()相当于什么?

这是我的C#代码:

var b = new byte[8];
b[0] = 0x20;
b[1] = 0x64;
b[2] = 0xa8;
b[3] = 0xac;
b[4] = 0xb6;
b[5] = 0x65;
b[6] = 0xe4;
b[7] = 0x40;
var dbl = BitConverter.ToDouble(b, 0);
var dt = DateTime.FromOADate(dbl);

这是输出:

  

2014-05-14T17:00:21

如何将此字节数组转换为java?

5 个答案:

答案 0 :(得分:5)

这看起来很有效......基本上ToBinary只返回一个表示,其中底部58位是自UTC中的BCL纪元以来的刻度。这段代码恰好反转了

private static final long UNIX_EPOCH = 62135596800000L;
public static Date fromDateTimeBinary(long value) {
    // Mask off the top bits, which hold the "kind" and
    // possibly offset.
    // This is irrelevant in Java, as a Date has no
    // notion of time zone
    value = value & 0x3fffffffffffffffL;
    // A tick in .NET is 100 nanoseconds. So a millisecond
    // is 10,000 ticks.
    value = value / 10000;
    return new Date(value - UNIX_EPOCH); 
}

我已针对“本地”DateTime和“UTC”DateTime对其进行了测试。它会将“未指定的”DateTime视为UTC格式。

总的来说,这并不理想,你应该在任何地方与尝试的地方交谈,以便更改为更便携的格式,但在此之前,这应该会有所帮助。不过要进一步测试!

答案 1 :(得分:5)

您是否意识到您的二进制数据是OLE Automation date值的二进制represantation?

因此,您应该从数组中获取long值,而不是获取double

var b = new byte[8];
b[0] = 0x20;
b[1] = 0x64;
b[2] = 0xa8;
b[3] = 0xac;
b[4] = 0xb6;
b[5] = 0x65;
b[6] = 0xe4;
b[7] = 0x40;
var dbl = BitConverter.ToDouble(b, 0);
var dt = DateTime.FromOADate(dbl);
Console.WriteLine("{0:s}", dt);

结果是:

2014-05-14T17:00:21

我认为有效的问题应该是: Java中DateTime.FromOADate()的等价物是什么?

答案是:

public static Date fromDoubleToDateTime(double OADate) 
{
    long num = (long) ((OADate * 86400000.0) + ((OADate >= 0.0) ? 0.5 : -0.5));
    if (num < 0L) {
        num -= (num % 0x5265c00L) * 2L;
    }
    num += 0x3680b5e1fc00L;
    num -=  62135596800000L;

    return new Date(num);
}

答案 2 :(得分:1)

DateTime.FromBinary()反序列化特定于.NET的序列化版本DateTime。它仅适用于DateTime.ToBinary()调用生成的二进制数据,而不适用于任何标准输入数据。

没有Java等价物,因为Java DateTime类在Java中不存在。

如果您尝试将.NET DateTime对象保存为二进制格式,并将其读入Java应用程序,则应使用其他格式。例如,自UNIX纪元以来的秒数。

答案 3 :(得分:0)

C#的二进制序列化是特定于.NET的,因为它将Ticks属性序列化为Int64,另外还有Kind-property,而Javas DateTime通常基于unixtime(自1970年以来的millis)。

所以我认为你不会在Java中找到一个等价的框架。看看这篇StackOverflow文章,了解如何在Java中获得Ticks等价物:C# DateTime.Ticks equivalent in Java

我也会快速给出Joda-Time。也许你会在那里找到一种实用方法。

答案 4 :(得分:0)

您应该选择更有意义的交换格式。

  • 如果您可以传递字符串,请使用ISO-8601格式。在.Net中,您可以使用yourDateTime.ToString("o")

  • 如果你想要更紧凑的东西,可以传递一个时间戳 - 例如自1970年1月1日UTC以来的一个长整数毫秒。

不要传递DateTime.ToBinary的输出。您将不得不在Java中实现许多不值得的东西。具体做法是:

  • Kind的{​​{1}}属性作为数据的一部分嵌入。您必须将其过滤掉并进行解释。 Java中没有任何直接的等价物。

  • 您可以看到in the .Net Framework Reference SourceDateTime必须处理各种时区转换 - 如果您一次序列化FromBinary DateTimeLocal区域并在另一个区域反序列化。