-2

How do I convert a Foxpro 8-byte datetime into a Java Date object?

I saw the same question on the site here:

How can i interpret "FoxPro" dbf file date time field (eight-byte) in my c++ program?

but that answer is in C++, and I don't know how to apply it to Java.

Community
  • 1
  • 1

1 Answers1

2

I don't have much data for testing, but here is a class that gives me the correct answer based on the example given in the comments to the question you mentioned.

It is worth mentioning that the answer to the C++ question is wrong. The value is not a double. This solution is based on the information given in this question (though not on its answer), which tells us that the date actually consists of two integers.

import java.nio.ByteBuffer;
import java.util.Date;

class FoxProDateConverter {

    private static final long BASE_FOXPRO_MILLIS = 210866803200000L;
    private static final long DAY_TO_MILLIS_FACTOR = 24L * 60L * 60L * 1000L;

    public static Date convert( byte[] foxProDate ) {

        if ( foxProDate.length != 8 ) {
            throw new IllegalArgumentException("FoxPro date must be 8 bytes long");
        }

        // FoxPro date is stored with bytes reversed.

        byte[] reversedBytes = new byte[8];
        for ( int i = 0;  i < 8; i++ ) {
            reversedBytes[i] = foxProDate[8 - i - 1];
        }

        // Grab the two integer fields from the byte array

        ByteBuffer buf = ByteBuffer.wrap(reversedBytes);

        long timeFieldMillis = buf.getInt();
        long dateFieldDays = buf.getInt();

        // Convert to Java date by converting days to milliseconds and adjusting
        // to Java epoch.

        return new Date(dateFieldDays * DAY_TO_MILLIS_FACTOR - BASE_FOXPRO_MILLIS + timeFieldMillis);

    }

    public static void main(String[] args) {

        byte[] bytes = {0x0E, 0x61, 0x25, 0x00, (byte)0xF8, (byte) 0xBF, (byte) 0xEA, 0x02};

        Date d = FoxProDateConverter.convert(bytes);
        System.out.println( d );
    }

}
Community
  • 1
  • 1
RealSkeptic
  • 33,993
  • 7
  • 53
  • 79
  • Thanks a lot RealSkeptic, it's exactly the good result (just an offset of one hour). – Jean-Paul Parent Jan 31 '15 at 14:06
  • @Jean-PaulParent Right. I calculated the `BASE_FOXPRO_MILLIS` for my own time zone. I have corrected it in my answer now, so it will give you the correct time - for UTC (that is, it will only print 13:35:39 if you use a `DateFormat` with the `UTC` timezone). – RealSkeptic Jan 31 '15 at 15:28
  • Another (unofficial) reference describing FoxPro's internal DATETIME format can be found in an answer on another site [here](http://www.experts-exchange.com/Programming/Languages/Java/J2EE/JSP/Q_20585197.html#a10149637). – Gord Thompson Feb 23 '15 at 11:33