YARN-11116. Migrate Times util from SimpleDateFormat to thread-safe DateTimeFormatter class (#4242)

Co-authored-by: Jonathan Eagles <jeagles@verizonmedia.com>
Signed-off-by: Akira Ajisaka <aajisaka@apache.org>
This commit is contained in:
jteagles 2022-05-02 13:14:26 -05:00 committed by GitHub
parent a74acc755e
commit d4a91bd0c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 20 deletions

View File

@ -19,8 +19,9 @@
package org.apache.hadoop.yarn.util; package org.apache.hadoop.yarn.util;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.time.Instant;
import java.util.Date; import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -31,23 +32,16 @@ public class Times {
private static final Logger LOG = private static final Logger LOG =
LoggerFactory.getLogger(Times.class); LoggerFactory.getLogger(Times.class);
static final String ISO8601DATEFORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; static final String ISO8601_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
// This format should match the one used in yarn.dt.plugins.js // This format should match the one used in yarn.dt.plugins.js
static final ThreadLocal<SimpleDateFormat> dateFormat = static final DateTimeFormatter DATE_FORMAT =
new ThreadLocal<SimpleDateFormat>() { DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss Z yyyy").withZone(
@Override protected SimpleDateFormat initialValue() { ZoneId.systemDefault());
return new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy");
}
};
static final ThreadLocal<SimpleDateFormat> isoFormat = static final DateTimeFormatter ISO_OFFSET_DATE_TIME =
new ThreadLocal<SimpleDateFormat>() { DateTimeFormatter.ofPattern(ISO8601_DATE_FORMAT).withZone(
@Override ZoneId.systemDefault());
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat(ISO8601DATEFORMAT);
}
};
public static long elapsed(long started, long finished) { public static long elapsed(long started, long finished) {
return Times.elapsed(started, finished, true); return Times.elapsed(started, finished, true);
@ -83,8 +77,7 @@ public static long elapsed(long started, long finished, boolean isRunning) {
} }
public static String format(long ts) { public static String format(long ts) {
return ts > 0 ? String.valueOf(dateFormat.get().format(new Date(ts))) return ts > 0 ? DATE_FORMAT.format(Instant.ofEpochMilli(ts)) : "N/A";
: "N/A";
} }
/** /**
@ -94,7 +87,7 @@ public static String format(long ts) {
* @return ISO 8601 formatted string. * @return ISO 8601 formatted string.
*/ */
public static String formatISO8601(long ts) { public static String formatISO8601(long ts) {
return isoFormat.get().format(new Date(ts)); return ISO_OFFSET_DATE_TIME.format(Instant.ofEpochMilli(ts));
} }
/** /**
@ -109,6 +102,6 @@ public static long parseISO8601ToLocalTimeInMillis(String isoString)
if (isoString == null) { if (isoString == null) {
throw new ParseException("Invalid input.", -1); throw new ParseException("Invalid input.", -1);
} }
return isoFormat.get().parse(isoString).getTime(); return Instant.from(ISO_OFFSET_DATE_TIME.parse(isoString)).toEpochMilli();
} }
} }

View File

@ -21,6 +21,12 @@
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import static org.apache.hadoop.yarn.util.Times.ISO8601_DATE_FORMAT;
public class TestTimes { public class TestTimes {
@Test @Test
@ -61,4 +67,15 @@ public void testFinishTimesAheadOfStartTimes() {
elapsed = Times.elapsed(Long.MAX_VALUE, 0, true); elapsed = Times.elapsed(Long.MAX_VALUE, 0, true);
Assert.assertEquals("Elapsed time is not -1", -1, elapsed); Assert.assertEquals("Elapsed time is not -1", -1, elapsed);
} }
@Test
public void validateISO() throws IOException {
SimpleDateFormat isoFormat = new SimpleDateFormat(ISO8601_DATE_FORMAT);
for (int i = 0; i < 1000; i++) {
long now = System.currentTimeMillis();
String instant = Times.formatISO8601(now);
String date = isoFormat.format(new Date(now));
Assert.assertEquals(date, instant);
}
}
} }