Incorrect Date marshalling
Two issues:
Issue #1:
- create variant with type Date in COM
- get its value through com4j.
- 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:
- 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"
- get its value through com4j
- The value will be off from what you generated in COM by 1 hour. Seems there is bug with DST processing
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;
}