Date WTF



  • There is an order system that feeds records via an Oracle DB into our system (both in Java) as part of a long daisy chain of processing systems. On each order, there is a transaction-date field passed as a millisecond count in a Java long. Our system does something like:

       long START_OF_DAY = ...;	// initialization section: y-m-d h-m-s-ms
       long END_OF_DAY   = ...;	// initialization section: y-m-d h-m-s-ms
       ...
       if (START_OF_DAY < order.getTimestamp() && order.getTimestamp() <= END_OF_DAY) { ... }

    The test was failing for several thousand orders per day. Naturally, our system was to blame because the test that chucked the order was in our code. The developers on the other team said that they could prove that the dates were valid because when they printed them out via:

       System.out.println(new SimpleDateFormat("MM/dd/yyyy HH🇲🇲ss.SSS").format(new Date(order.getTimestamp())));

    the dates were correct. It turns out that the millisecond value for their date was negative. Per the Java spec, negative numbers indicate time before Jan 1, 1970.  In actuality, their transaction dates were BC. Our test correctly chucked them as not being part of the current business day.

    Naturally, word of these BC transactions spread throughout the firm like wildfire because all of the chained systems were affected, and everyone's reports (including those sent to regulatory authorities) were out of whack.

    When will people learn?



  • Not to excuse this stupidity, but it is kind of a gotcha that BC dates look exactly like AD ones unless you include the era in the format string.  And it's especially tricky because even Java's Date.toString() method does not put the era in.
     



  • I don't get it.  If the negative dates are offset relative to 1970, then if you printed out the negative dates, wouldn't they show up as 1943, 1944, 1945, etc?  Or did you get huge negative values (due to overflow or something) that went so far back that the date really was 2007 BC and if you flipped the sign the dates would show up as 5947 AD?



  • @mountain said:

    I don't get it.  If the negative dates are offset relative to 1970, then if you printed out the negative dates, wouldn't they show up as 1943, 1944, 1945, etc?  Or did you get huge negative values (due to overflow or something) that went so far back that the date really was 2007 BC and if you flipped the sign the dates would show up as 5947 AD?

    No, if I understand it correctly, the dates were the BC version of the correct AD date.  For example, the following Java code:

        long time = -3978l * 365l * 86400l * 1000l;
        Date d1 = new Date (time);
        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH🇲🇲ss.SSS");
        Date d2 = sdf.parse(sdf.format(d1));

        System.out.println(sdf.format(d1));
        System.out.println(d1.getTime());

        System.out.println(sdf.format(d2));
        System.out.println(d2.getTime());

    results in:

     09/08/2007 19:00:00.000
    -125450208000000
    09/08/2007 19:00:00.000
    1189292400000


Log in to reply