8

I am using this simple date format

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS Z");

the problem is when I use this it takes too long to convert the time, in logcat I see something like this

I/Resources( 4284): Loaded time zone names for en in 272ms.
I/Resources( 4284): Loaded time zone names for en in 194ms.
I/Resources( 4284): Loaded time zone names for en in 112ms.
I/Resources( 4284): Loaded time zone names for en in 111ms.
I/Resources( 4284): Loaded time zone names for en in 113ms.
I/Resources( 4284): Loaded time zone names for en in 127ms.
I/Resources( 4284): Loaded time zone names for en in 253ms.
I/Resources( 4284): Loaded time zone names for en in 110ms.
I/Resources( 4284): Loaded time zone names for en in 154ms.
I/Resources( 4284): Loaded time zone names for en in 112ms.

How can I use simple date formater but to speed the things up, I do not want to take ~150ms for every conversion...

Does anybody had this problem before ?

Lukap
  • 31,523
  • 64
  • 157
  • 244
  • If it is the timezone that slows it down, you could calculate it once and then add it as a string to each formatting, as the timezone is unlikely to change. – Jave Jan 16 '12 at 14:11
  • this is the code, the delay is on new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS Z"); and it is becouse I have the zone included, if I run my code with new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); [with out the timezone] it works just fine, the only problem is when the time zone is included it simply takes too much time I do not know why – Lukap Jan 16 '12 at 14:12
  • @Jave can you show me how to do that with code ? – Lukap Jan 16 '12 at 14:13
  • related issue here: http://code.google.com/p/android/issues/detail?id=3147 – Somatik Aug 18 '12 at 15:15

2 Answers2

11

This is due to the lazy initialization of the timezone zone strings. Only the first call will take this long. If the SimpleDateFormat is used again afterwards it's loaded from cache and shouldn't take that long anymore.

Before this was changed it was done when the class was loaded and thus the start of an activity took those 2-3 seconds longer. This had a much worse impact on the user experience than if it takes those seconds when it's actually used the first time. The problem is that there's no way right now to circumvent this issue due to the design of the SimpleDateFormat api. Only faster phones might fix this by just taking less time to collect those strings.

The caching happens in the DateFormatSymbols that SimpleDateFormat is using. By reusing that instance it's possible to only have to load the stings once (for the same loale). You could also create that Instance in a thread at the startup of the activity so that it's already cached once it's used. To init the strings just call .hashCode() which does force initialize the cache. A bit faster but less simple would be to serialize the instance. This also forces the cache to be initialized.

In the interim, consider using AsyncTask to "warm up" SimpleDateFormat in your process before you need it. Just parse some date in the AsyncTask doInBackground() to get it to load the timezones sometime when it will not impact the user so much. Once initialized in your process, SimpleDateFormat will run quickly until your process is terminated.

Pulkit Goyal
  • 5,604
  • 1
  • 32
  • 50
4

This isn't true on recent releases of Android (and from the text of the log message I can tell that you're running an old release; modern releases tell you how much time was spent in icu4c versus managed code). Note that the answer from "Pulkit Goyal" was copy and pasted from http://code.google.com/p/android/issues/detail?id=3147 and the text refers to Donut. I've rewritten this code several times since then. Currently, en_US and the system's default locale (at boot time) are cached in the zygote. There's a further per-app cache so that for other locales you should only pay once.

The worst case in modern releases is where the user changes the system's default locale. It would require a restart of the zygote (a "runtime restart" or a reboot) to get the new default locale's time zone strings cached in the zygote where they could be shared. (i described this behavior in comment 11 on the bug, and it's shipped with ICS.)

Elliott Hughes
  • 4,595
  • 2
  • 23
  • 21
  • I am seeing these log statements happen several times, after I load an RSS feed using HorrorRSS or ROME libraries. It does not appear anything is getting cached as the log statements are printed each time I load a new feed, even in the same method call right after one another. The strange thing is I am not using SimpleDateFormat. I have an active question open about this in case you're curious: http://stackoverflow.com/questions/12762478/android-loaded-time-zone-names-for-en-in-ms – The Awnry Bear Oct 06 '12 at 18:18