com4j icon indicating copy to clipboard operation
com4j copied to clipboard

Incorrect Date marshalling

Open ipalopezhentsev opened this issue 11 years ago • 1 comments

Two issues:

Issue #1:

  1. create variant with type Date in COM
  2. get its value through com4j.
  3. the value will be off from what you generated in COM by 1 second Conjecture is you don't account for leap seconds while evaluating java.util.Date's time.

Issue #2:

  1. Create variant with type Date in COM with value in last days of March or October (time of switching to daylight savings time). For example "Oct 31 08:00:45 2010"
  2. get its value through com4j
  3. The value will be off from what you generated in COM by 1 hour. Seems there is bug with DST processing

ipalopezhentsev avatar Jul 24 '14 21:07 ipalopezhentsev

Something is definitely off here...

When setting the current date (i.e. new java.util.Date()) to an iTunes object, I currently get a time that is 2 hours later than the time I set (I tested this today, on 10/24/2014) with CEST as the local time.

When looking at the code in Variant.java, I am wondering whether the correction for ZONE_OFFSET and DST_OFFSET is at all necessary. I would assume that t is already an "absolute" time that just needs the "absolute" offset of 2209161600000L added... At least that would explain why in my case values shown in iTunes are 2h off (DST+ZONE offsets are currently exactly 2h).

When I set a time in December (obviously no DST), it still shows up as 1h later in iTunes, exactly my current time zone offset (CET).

But then again, VT_Date seems to be a clusterf*** anyhow, as pointed out here.

Or is it just iTunes that interprets the VT_Date as UTC time, not as local time?

/**
 * Opposite of the {@link #toDate(double)} method.
 */
static double fromDate(Date dt) {

    // the number of milliseconds since January 1, 1970, 00:00:00 GMT
    long t = dt.getTime();

    // the number of milliseconds since January 1, 1970, 00:00:00 Local Time
    Calendar c = new GregorianCalendar();
    c.setTime(dt);
    t += (c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET)) ;

    // the number of milliseconds since December 30, 1899, 00:00:00 Local Time
    t += 2209161600000L;

    // DATE is an offset from "30 December 1899"
    if (t < 0) {
        // -0.3 -> -0.7
        long offset = -(t % MSPD);    // TODO: check
        t = t - MSPD + offset;
    }
    double d = ((double) t) / MSPD;
    return d;
}

hendriks73 avatar Oct 24 '14 17:10 hendriks73