Reputation: 11
I want to create a Java class with thread-safe static methods to parse dates. I understand that some of the Java 7 (and earlier) date time classes are not thread-safe. What is the best thread-safe implementation in Java 8 of this functionality:
String text = "5/16/2008";
long timestamp = DateUtil.getTimestamp(text);
In Java 7 and earlier, you would do this:
public class DateUtil {
public static long getTimestamp(String text) {
DateFormat df = new SimpleDateFormat("M/d/yyyy");
df.setTimeZone(TimeZone.getTimeZone("America/New_York"));
long timestamp = df.parse(text).getTime();
return timestamp;
}
}
But instead of creating a new instance of DateFormat
for every call, I want to share a single static instance for all calls to this static getTimestamp
method. My understanding is that this is not thread-safe.
One key requirement is that the text I want to parse has a short date like "5/16/2008" without HH:mm:ss resolution.
I also don't want to use a third party library like Joda-Time, but rather only standard Java 8 classes.
Upvotes: 1
Views: 2616
Reputation: 3901
As stated in ck1's answer, usage of java.time
API is a better approach than the legacy classes. DateTimeFormatter
is immutable and thread-safe, and using a static final instance of it will solve your problem.
The only part where I differ from that answer is in the code , where the Date
class is used to get the time. I would like to take the java.time
approach here as well. Below is my version :
public class DateUtil {
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/d/yyyy");
public static long getTimestamp(String text) {
LocalDate localDate = LocalDate.parse(text, formatter);
return Instant.from(localDate.atStartOfDay(ZoneId.systemDefault())).toEpochMilli();
}
public static void main(String[] args) {
String text = "5/16/2008";
long timestamp = DateUtil.getTimestamp(text);
System.out.println(timestamp);
}
}
Upvotes: 0
Reputation: 1475
You can use joda-time
lib. DateTime
is immutable - and once created the values do not change, so class can safely be passed around and used in multiple threads without synchronization.
A companion mutable class to DateTime is MutableDateTime
, of which the class can be modified and are not thread-safe.
DateTimeFormatter formatter = DateTimeFormat.forPattern("M/d/yyyy'T'HH:mm:ss.SSSZZ")
.withLocale(Locale.ROOT).withChronology(ISOChronology.getInstanceUTC());
DateTime dt = formatter.parseDateTime(text);
Reference of DateTimeFormatt
: DatetimeFormat api.
Upvotes: 0
Reputation: 5443
Here's a version of your code refactored to use the java.time.*
package in Java 8. It uses a static final
formatter instance, which is thread-safe and immutable, unlike java.text.SimpleDateFormat
.
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
public class DateUtil {
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/d/yyyy");
public static long getTimestamp(String text) {
LocalDate localDate = LocalDate.parse(text, formatter);
return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()).getTime();
}
}
Upvotes: 5