1

Here is the issue I'm having. In my kotlin code (in an Android project), I have something like this:

val rDate = Util.formatDateAsIso8601(Date())

The formatDateAsIso8601(Date inputDate) is a Java method and looks like this:

public static String formatDateAsIso8601(final Date inputDate) {
    TimeZone tz = TimeZone.getDefault();
    mDateFormat.setTimeZone(tz);
    return mDateFormat.format(inputDate);
}

where

mDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.ENGLISH);

Once I get rDate, it populates an Object field and then serialized to json. The issue is that the value for the date is really weird. The first issue I saw was getting a date of 2018-11-31, which is an invalid date. Now I'm seeing values with extra 0's, such as '2018-11-007T20:09:26.533-0500' and '2018-0011-007T020:18:00.367-0500' and even '2018-0011-007T020:27:22.712-0500'. This issue is happening sporadically. Most of the time the dates are fine, but sometimes there are quite a few instances of this stuff happening, and it really only started happening fairly relatively recently. Any ideas what is going on here?

--Edit-- I now create the SimpleDateFormat object with every call, but I am still getting these weird date values. Here is the new format method:

public static String formatDateAsIso8601(final Date inputDate) {
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.ENGLISH);
    TimeZone tz = TimeZone.getDefault();
    dateFormat.setTimeZone(tz);
    return dateFormat.format(inputDate);
}
salbury
  • 91
  • 1
  • 7
  • 2
    `SimpleDateFormat` is not thread-safe, see e.g. https://stackoverflow.com/questions/6137548/can-we-declare-simpledateformat-objects-as-static-objects/30106763 – Marvin Nov 08 '18 at 19:18
  • 1
    FYI, the terribly troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Nov 08 '18 at 19:40
  • I am not creating a new SimpleDateFormat with every call, but I'm still getting these weird dates. – salbury Nov 08 '18 at 19:48
  • I also can't always use the new Java 8 stuff since this is for Android. – salbury Nov 08 '18 at 20:41
  • *this is for an Android project so I can't really use the new Java 8 stuff.* Indeed you can, and should certainly consider. java.time, the modern and thread-safe Java date and time API, has been backported. You need [the ThreeTenABP library](https://github.com/JakeWharton/ThreeTenABP). See also [How to use ThreeTenABP in Android Project](https://stackoverflow.com/questions/38922754/how-to-use-threetenabp-in-android-project). – Ole V.V. Nov 09 '18 at 02:50
  • The examples you report from the earlier version of your format method certainly smell like a concurrency issue. Would you report a couple of examples of incorrect formatted strings obtained from the new version? I’d very much like to see if they are different and whether anyone here will be able to spot any other possible explanation. – Ole V.V. Nov 09 '18 at 02:55
  • Ah, ok I will definitely consider that library. Thanks for bringing that to my attention. I'm not so sure it's not a concurrency issue, although I agree it has that feel. I've been using this code for a while and haven't had any issues. Plus after I made the change so it creates a new SimpleDateFormat object with each call, concurrency shouldn't have any effect, right? Here are some of the dates I get using the latest code: '2018-11-0008T14:26:38.197-0500', '2018-011-08T014:18:40.398-0500', '2018-11-008T14:30:03.226-0500'. – salbury Nov 10 '18 at 00:36

1 Answers1

4

SimpleDateFormat is not thread safe so it should not be shared. Create new date format object in each call to formatDateAsIso8601.

Mika
  • 1,256
  • 13
  • 18