1

I'm working on migrating some data (in java) where I'm pulling date strings from several different sources (that use different formats) and I need to send them along in a consistent format. So I have a method that takes a string (and the source it came from so I know which format to use) and converts it into a date, so I can go from there.

Problem: all of the formats work perfectly except for the first one: the resulting date values returned are between 0-17 minutes off from the original string I give it!

// Take a string, convert to a date
public static Date convertStringToDate (String dateString, String source) {
    String dateFormat = null;
    switch (source)
    {
        case "DATA": //@FIXME: these vary 0-17 minutes off!
            dateFormat = "yyyy-MM-dd HH:mm:ss.SSSSSS"; // 2018-08-29 20:09:26.863631 (ex: mailing list records)
            break;
        case "DATA_EN": // encrypted dates use a different format
            dateFormat = "yyyy-MM-dd HH:mm:ss ZZZZ"; // 2019-06-12 14:33:27 +0000 (ex: encrypted_patient_information_complete_at)
            break;
        case "DatStat":
            dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"; // 2018-08-29T14:33:49Z (ex: followup survey)
            break;
        case "download":
            if (dateString.length() > 10 ){ // the majority of these will be in format 1/9/16 9:30
                dateFormat = "M/dd/yy HH:mm"; // 2/16/18 19:58 (ex: csv from datstat)
            } else { // dates submitted at midnight lose their time and have format 9-Jan-16
                dateFormat = "dd-MMM-yy"; // 9-Jan-16
            }
            break;
        default:
            dateFormat = "INVALID SOURCE VALUE GIVEN";
            break;
    }

    SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
    Date dt = null;
    try {
        dt = sdf.parse(dateString);
    }
    catch (Exception ex) {
        throw new RuntimeException("An error has occurred trying to parse timestamp." + dateString, ex);
    }
    return dt;
}

Example input/output:

  • String saved: "2019-06-12 14:33:08.712754"
  • Date we get: "2019-06-12T14:45:00Z"

I'm wondering if there's something particular to this format that I'm not getting right, but haven't found anything in reading around. Does anyone see what the issue could be? Or have you seen this before?

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Diane Kaplan
  • 1,626
  • 3
  • 24
  • 34
  • 1
    My workaround in the meantime is to strip off the milliseconds in the string, and use "yyyy-MM-dd HH:mm:ss", which works correctly. – Diane Kaplan Sep 12 '19 at 19:00
  • 1
    I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use `LocalDateTime`, `DateTimeFormatter` and other classes from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Sep 13 '19 at 06:59
  • 1
    Possible duplicate of [Date object SimpleDateFormat not parsing timestamp string correctly in Java (Android) environment](https://stackoverflow.com/questions/5636491/date-object-simpledateformat-not-parsing-timestamp-string-correctly-in-java-and) and/or of [Changing Java Timestamp format causes a change of the timestamp](https://stackoverflow.com/questions/50908447/changing-java-timestamp-format-causes-a-change-of-the-timestamp) – Ole V.V. Sep 13 '19 at 07:01
  • The apparently little attention to your question may have been due to poor tagging. The sdf tag is not for simpledateformat. I have tried to improve, I hope it’s not too late (older questions also get less attention, not sure whether it happens after hours or only after days). – Ole V.V. Sep 13 '19 at 07:03
  • One more similar question: [SimpleDateFormat not parsing time correctly \[duplicate\]](https://stackoverflow.com/questions/54635330/simpledateformat-not-parsing-time-correctly). – Ole V.V. Sep 13 '19 at 07:06
  • Yes it sounds like SimpleDateFormat simply distorts milliseconds even when formatted 'correctly'. The goals of the program don't really need a more robust datetime library, so I'll keep my little workaround of stripping the milliseconds. Thank you, all!! – Diane Kaplan Sep 13 '19 at 13:18

1 Answers1

1

As Other have mentionned in comment, other thread answers this well: https://stackoverflow.com/a/6157860/5190019

The fact is that SSSSSS doesn't exist as a format for this class, it expects only 3 number for milliseconds. So it is interpreted as such. DateFormat will interpret 712754 as 712754/1000 seconds rather than 0.712754 seconds. And if you do the calculus it's 11,86. minutes, which mean 11mn52 seconds. So 33:08+11:52, is 45:00, the result you get.

As for the solution, you can either strip the rest of the milliseconds part because you don't need it anyway (as you did) or use another class (all comments from Ole V.V are on point).

Asoub
  • 2,273
  • 1
  • 20
  • 33