I'm looking for a thread-safe replacement for SimpleDateFormat. parseObject on good old FastDateFormat isn't implemented and just throws an error. Any ideas? I don't need anything fancy, just thread-safety and the ability to handle this pattern: "yyyy-MM-dd".
- 59,536
- 22
- 119
- 123
5 Answers
If at all possible, use Joda Time. Its date/time parsers are thread-safe, and it's generally a much nicer API than Date/Calendar.
You can use just its parsers and then convert the return values to Date, but personally I would recommend using the whole library instead.
- 1,335,956
- 823
- 8,931
- 9,049
As outlined in this post you can either synchronise, use thread locals or Joda-Time.
For example, using ThreadLocals:
public class DateFormatTest {
private static final ThreadLocal<DateFormat> df
= new ThreadLocal<DateFormat>(){
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyyMMdd");
}
};
public Date convert(String source)
throws ParseException{
Date d = df.get().parse(source);
return d;
}
}
- 254,755
- 72
- 386
- 405
-
1+1 No blocking. Trade memory for thread safety. No external big library for simple case. – shellholic Jan 11 '11 at 14:42
-
1Your answer is a collateral victim of a high reputation bomb. – shellholic Jan 11 '11 at 14:48
java.time
The java.time types are thread-safe. The java.time API (the modern Date-Time API*) has been there since March 2014 as part of Java SE 8 standard library.
Quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Demo:
import java.time.LocalDate;
public class Main {
public static void main(String[] args) {
String strDate = "2021-06-13";
LocalDate date = LocalDate.parse(strDate);
System.out.println(date);
}
}
Output:
2021-06-13
The modern Date-Time API is based on ISO 8601 and does not require using a DateTimeFormatter object explicitly as long as the Date-Time string conforms to the ISO 8601 standards. You might have noticed that I have not used a parsing type (DateTimeFormatter) in the above code because yyyy-MM-dd is also the ISO 8601 pattern for a date.
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
- 262,936
- 84
- 758
- 1,028
- 62,771
- 5
- 54
- 92
Why not to put the call of SimpleDateFormat.parseObject() into your own synchronized block?
- 111,884
- 15
- 126
- 200
Found a solution.
public class ThreadSafeSimpleDateFormat {
private DateFormat df;
public ThreadSafeSimpleDateFormat(String format) {
this.df = new SimpleDateFormat(format);
}
public synchronized String format(Date date) {
return df.format(date);
}
public synchronized Date parse(String string) throws ParseException {
return df.parse(string);
}
}
- 659
- 5
- 10
-
That may not perform well, but it's easy. Performance will depend on how many threads are really trying to access the formatter at the same time. I would try this (or just wrapping your calls to SimpleDateFormat in a synch block) first to see if it's really an issue. – AngerClown Jan 11 '11 at 14:31