I think it's thread safe in this way. If an object can't change(theoretically immutable) then it is safe to use it from different threads. You can make getFormatter and formatDate static, since they don't use any field from the object.
SimpleDateFormat is indeed not thread-safe - this means you must not use the same SimpleDateFormat in different threads at the same time. It doesn't matter if you don't change the format; the SimpleDateFormat object seems to have some internal state that is modified when you call format().
Your code is not thread-safe.
Wrap your SimpleDateFormat object in a ThreadLocal: