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>
(cherry picked from commit d4a91bd0c0
)
This commit is contained in:
parent
4f9e607126
commit
f155abc572
|
@ -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 class Times {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 class Times {
|
||||||
* @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 class Times {
|
||||||
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,12 @@ package org.apache.hadoop.yarn.util;
|
||||||
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 class TestTimes {
|
||||||
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue