What is the equivalent of DateTime.FromOADate() in Java (double to Datetime in Java)

StackOverflow https://stackoverflow.com/questions/23670516

  •  23-07-2023
  •  | 
  •  

Question

C# has a DateTime.FromOADate() method.

What is the equivalent of DateTime.FromOADate() in Java ?

This is my C# code :

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);

This is the output :

2014-05-14T17:00:21

How can i convert this byte array to java?

Était-ce utile?

La solution

Did you realize that your binary data is the binary represantation of an OLE Automation date value?

So instead of getting long, you should get a double value from your array.

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);

Result is :

2014-05-14T17:00:21

I think the valid question should be: What is the equivalent of DateTime.FromOADate() in Java ?

Answer is:

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);
}

Autres conseils

This looks like it works... basically ToBinary just returns a representation where the bottom 58 bits are the ticks since the BCL epoch in UTC. This code just reverses that

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); 
}

I've tested that for a "local" DateTime and a "UTC" DateTime. It will treat an "unspecified" DateTime as being in UTC.

Overall it's not ideal, and you should talk to wherever you're getting the data from to try to change to a more portable format, but until then this should help. Do test it further though!

DateTime.FromBinary() deserializes a .NET-specific serialized version of DateTime. It works only with the binary data produced from a DateTime.ToBinary() call, not with any standard input data.

There is no Java equivalent, because the .NET DateTime class doesn't exist in Java.

If you are trying to save a .NET DateTime object to a binary format, and read it in to a Java application, you should be using a different format. For example, seconds since the UNIX epoch.

C#'s binary serialization is .NET specific as it serializes the Ticks-property as Int64 and additionally the Kind-property whereas Javas DateTime is typically based on the unixtime (millis since 1970).

So i think you will not find a framework equivalent in Java. Have a look at this StackOverflow post for information how to get a Ticks equivalent in Java: C# DateTime.Ticks equivalent in Java

I also would give Joda-Time a quick shot. Maybe you will find a utility method there.

You should choose an interchange format that makes more sense.

  • If you can pass a string, use the ISO-8601 format. In .Net, you would use yourDateTime.ToString("o").

  • If you want something more compact, pass a timestamp - such as a long integer of milliseconds since 1/1/1970 UTC.

Don't pass the output of DateTime.ToBinary. You would have to implement a lot of things in Java that would not be worth it. Specifically:

  • The Kind property of the DateTime is embedded as part of the data. You'd have to filter it out and interpret it. There isn't any direct equivalent in Java.

  • You can see in the .Net Framework Reference Source, that FromBinary has to deal with various time zone conversions - in case you serialize a DateTime with Local kind in one time zone and deserialize it in another.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top