33
33
* and a time.
34
34
*/
35
35
public class UtcTimestampConverter extends AbstractDateTimeConverter {
36
- private static final ThreadLocal <UtcTimestampConverter > utcTimestampConverter = new ThreadLocal <UtcTimestampConverter >();
37
- private final DateFormat utcTimestampFormat = createDateFormat ("yyyyMMdd-HH:mm:ss" );
38
- private final DateFormat utcTimestampFormatMillis = createDateFormat ("yyyyMMdd-HH:mm:ss.SSS" );
36
+
37
+ protected static final class Context {
38
+ private final DateFormat utcTimestampFormat = createDateFormat ("yyyyMMdd-HH:mm:ss" );
39
+ private final DateFormat utcTimestampFormatMillis = createDateFormat ("yyyyMMdd-HH:mm:ss.SSS" );
40
+ private final StringBuffer buffer = new StringBuffer (128 );
41
+ }
42
+
43
+ private static final ThreadLocal <Context > utcTimestampConverter = new ThreadLocal <Context >() {
44
+ @ Override
45
+ protected Context initialValue () {
46
+ return new Context ();
47
+ }
48
+ };
49
+
39
50
private final static ConcurrentHashMap <String , Long > dateCache = new ConcurrentHashMap <String , Long >();
40
51
41
52
/**
@@ -46,16 +57,32 @@ public class UtcTimestampConverter extends AbstractDateTimeConverter {
46
57
* @return the formatted timestamp
47
58
*/
48
59
public static String convert (Date d , boolean includeMilliseconds ) {
49
- return getFormatter (includeMilliseconds ).format (d );
60
+ Context context = utcTimestampConverter .get ();
61
+ try {
62
+ (includeMilliseconds ? context .utcTimestampFormatMillis : context .utcTimestampFormat )
63
+ .format (d , context .buffer , DontCareFieldPosition .INSTANCE );
64
+ return context .buffer .toString ();
65
+ } finally {
66
+ context .buffer .setLength (0 );
67
+ }
50
68
}
51
69
52
- private static DateFormat getFormatter (boolean includeMillis ) {
53
- UtcTimestampConverter converter = utcTimestampConverter .get ();
54
- if (converter == null ) {
55
- converter = new UtcTimestampConverter ();
56
- utcTimestampConverter .set (converter );
70
+ /**
71
+ * Convert a timestamp (represented as a Date) to a String.
72
+ *
73
+ * @param d the date to convert
74
+ * @param includeMilliseconds controls whether milliseconds are included in the result
75
+ * @param stringBuilder the out buffer to hold the formatted timestamp
76
+ */
77
+ public static void convert (Date d , StringBuilder stringBuilder , boolean includeMilliseconds ) {
78
+ Context context = utcTimestampConverter .get ();
79
+ try {
80
+ (includeMilliseconds ? context .utcTimestampFormatMillis : context .utcTimestampFormat )
81
+ .format (d , context .buffer , DontCareFieldPosition .INSTANCE );
82
+ stringBuilder .append (context .buffer );
83
+ } finally {
84
+ context .buffer .setLength (0 );
57
85
}
58
- return includeMillis ? converter .utcTimestampFormatMillis : converter .utcTimestampFormat ;
59
86
}
60
87
61
88
//
@@ -73,11 +100,11 @@ private static DateFormat getFormatter(boolean includeMillis) {
73
100
*/
74
101
public static Date convert (String value ) throws FieldConvertError {
75
102
verifyFormat (value );
76
- long timeOffset = (parseLong (value . substring ( 9 , 11 ) ) * 3600000L )
77
- + (parseLong (value . substring ( 12 , 14 ) ) * 60000L )
78
- + (parseLong (value . substring ( 15 , 17 ) ) * 1000L );
103
+ long timeOffset = (parseLong (value , 9 , 11 ) * 3600000L )
104
+ + (parseLong (value , 12 , 14 ) * 60000L )
105
+ + (parseLong (value , 15 , 17 ) * 1000L );
79
106
if (value .length () == 21 ) {
80
- timeOffset += parseLong (value . substring ( 18 , 21 ) );
107
+ timeOffset += parseLong (value , 18 , 21 );
81
108
}
82
109
return new Date (getMillisForDay (value ) + timeOffset );
83
110
}
0 commit comments