Skip to content

Commit fa8957d

Browse files
committed
Replace SimpleDateFormat with DateTimeFormatter
Replace usages of the non-thread-safe date formatter with java.time's DateTimeFormatter and related APIs to improve thread-safety and correctness when parsing/formatting dates and time zones. Update calendar parameter conversion to use ZonedDateTime/Instant and adapt log timestamp formatting to use DateTimeFormatter. Removes unused imports and modernizes date handling to avoid concurrency issues introduced by SimpleDateFormat. Collectively decided to use `DateTimeFormatter` instead of `FastDateTime`. Signed-off-by: Nico Piel <[email protected]>
1 parent d268252 commit fa8957d

File tree

2 files changed

+33
-16
lines changed

2 files changed

+33
-16
lines changed

server/src/com/mirth/connect/client/core/api/providers/CalendarParamConverterProvider.java

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,24 @@
99

1010
package com.mirth.connect.client.core.api.providers;
1111

12-
import java.lang.annotation.Annotation;
13-
import java.lang.reflect.Type;
14-
import java.text.ParseException;
15-
import java.text.SimpleDateFormat;
16-
import java.util.Calendar;
17-
1812
import javax.inject.Singleton;
1913
import javax.ws.rs.ProcessingException;
2014
import javax.ws.rs.ext.ParamConverter;
2115
import javax.ws.rs.ext.ParamConverterProvider;
2216
import javax.ws.rs.ext.Provider;
17+
import java.lang.annotation.Annotation;
18+
import java.lang.reflect.Type;
19+
import java.time.Instant;
20+
import java.time.ZoneId;
21+
import java.time.ZonedDateTime;
22+
import java.time.format.DateTimeFormatter;
23+
import java.time.format.DateTimeParseException;
24+
import java.util.Calendar;
2325

2426
@Provider
2527
@Singleton
2628
public class CalendarParamConverterProvider implements ParamConverterProvider {
27-
28-
private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
29+
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
2930

3031
@Override
3132
public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType, Annotation[] annotations) {
@@ -38,10 +39,16 @@ public T fromString(String value) {
3839
}
3940

4041
try {
41-
Calendar date = Calendar.getInstance();
42-
date.setTime(format.parse(value));
43-
return (T) date;
44-
} catch (ParseException e) {
42+
// Parse the incoming string as a ZonedDateTime using the given pattern
43+
ZonedDateTime zdt = ZonedDateTime.parse(value, FORMATTER);
44+
45+
Calendar calendar = Calendar.getInstance(java.util.TimeZone.getTimeZone(zdt.getZone()));
46+
calendar.setTimeInMillis(zdt.toInstant().toEpochMilli());
47+
48+
@SuppressWarnings("unchecked")
49+
T result = (T) calendar;
50+
return result;
51+
} catch (DateTimeParseException e) {
4552
throw new ProcessingException(e);
4653
}
4754
}
@@ -51,7 +58,15 @@ public String toString(T value) {
5158
if (value == null) {
5259
return null;
5360
}
54-
return format.format(((Calendar) value).getTime());
61+
62+
Calendar calendar = (Calendar) value;
63+
64+
// Build a ZonedDateTime from the Calendar (date/time + time zone)
65+
Instant instant = calendar.toInstant();
66+
ZoneId zoneId = calendar.getTimeZone().toZoneId();
67+
ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, zoneId);
68+
69+
return FORMATTER.format(zdt);
5570
}
5671
};
5772
}

server/src/com/mirth/connect/plugins/serverlog/ServerLogItem.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,16 @@
1010
package com.mirth.connect.plugins.serverlog;
1111

1212
import java.io.Serializable;
13-
import java.text.SimpleDateFormat;
13+
14+
import java.time.ZoneId;
15+
import java.time.format.DateTimeFormatter;
1416
import java.util.Date;
1517

1618
import org.apache.commons.lang3.StringUtils;
1719

1820
public class ServerLogItem implements Serializable {
1921

20-
public static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
22+
public static DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").withZone(ZoneId.systemDefault());
2123

2224
private String serverId;
2325
private Long id;
@@ -123,7 +125,7 @@ public void setThrowableInformation(String throwableInformation) {
123125
public String toString() {
124126
if (id != null) {
125127
StringBuilder builder = new StringBuilder();
126-
builder.append('[').append(DATE_FORMAT.format(date)).append("] ");
128+
builder.append('[').append(DATE_FORMAT.format(date.toInstant())).append("] ");
127129
builder.append(level);
128130
builder.append(" (").append(category);
129131
if (StringUtils.isNotBlank(lineNumber)) {

0 commit comments

Comments
 (0)