diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/Times.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/Times.java index 4234085ebe8..fed47e76af0 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/Times.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/Times.java @@ -20,6 +20,9 @@ import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.Date; import org.apache.commons.logging.Log; @@ -30,7 +33,7 @@ public class Times { private static final Log LOG = LogFactory.getLog(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"; static final ThreadLocal dateFormat = new ThreadLocal() { @@ -43,9 +46,12 @@ new ThreadLocal() { @Override protected SimpleDateFormat initialValue() { - return new SimpleDateFormat(ISO8601DATEFORMAT); + return new SimpleDateFormat(ISO8601_DATE_FORMAT); } }; + static final DateTimeFormatter ISO_OFFSET_DATE_TIME = + DateTimeFormatter.ofPattern(ISO8601_DATE_FORMAT).withZone( + ZoneId.systemDefault()); public static long elapsed(long started, long finished) { return Times.elapsed(started, finished, true); @@ -91,6 +97,9 @@ public static String format(long ts) { * @param ts to be formatted in ISO format. * @return ISO 8601 formatted string. */ + public static String formatISO8601Instant(long ts) { + return ISO_OFFSET_DATE_TIME.format(Instant.ofEpochMilli(ts)); + } public static String formatISO8601(long ts) { return isoFormat.get().format(new Date(ts)); } @@ -102,6 +111,13 @@ public static String formatISO8601(long ts) { * @return epoch time for local time zone. * @throws ParseException if given ISO formatted string can not be parsed. */ + public static long parseISO8601ToLocalTimeInMillisInstant(String isoString) + throws ParseException { + if (isoString == null) { + throw new ParseException("Invalid input.", -1); + } + return Instant.from(ISO_OFFSET_DATE_TIME.parse(isoString)).toEpochMilli(); + } public static long parseISO8601ToLocalTimeInMillis(String isoString) throws ParseException { if (isoString == null) { diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/util/TestTimes.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/util/TestTimes.java index 918743d02ff..7109497cc5e 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/util/TestTimes.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/util/TestTimes.java @@ -21,6 +21,8 @@ import org.junit.Assert; import org.junit.Test; +import java.io.IOException; + public class TestTimes { @Test @@ -61,4 +63,76 @@ public void testFinishTimesAheadOfStartTimes() { elapsed = Times.elapsed(Long.MAX_VALUE, 0, true); Assert.assertEquals("Elapsed time is not -1", -1, elapsed); } + @Test + public void performance() { + long start = System.currentTimeMillis(); + long sum = 0; + for(int i = 0; i < 1000000; i++) { + sum += Times.formatISO8601(System.currentTimeMillis()).length(); + } + long end = System.currentTimeMillis(); + System.out.println(end - start); + System.out.println(sum); + } + @Test + public void performanceInstant() { + long start = System.currentTimeMillis(); + long sum = 0; + for(int i = 0; i < 1000000; i++) { + sum += Times.formatISO8601Instant(System.currentTimeMillis()).length(); + } + long end = System.currentTimeMillis(); + System.out.println(end - start); + System.out.println(sum); + } + @Test + public void performanceRoundTripInstant() throws Exception { + long start = System.currentTimeMillis(); + for(int i = 0; i < 1000000; i++) { + long now = System.currentTimeMillis(); + String instant = Times.formatISO8601Instant(now); + long epoch = Times.parseISO8601ToLocalTimeInMillisInstant(instant); + if (now != epoch) { + System.out.println(now); + System.out.println(epoch); + throw new IOException("millis different"); + } + } + long end = System.currentTimeMillis(); + System.out.println(end - start); + } + @Test + public void performanceRoundTrip() throws Exception { + long start = System.currentTimeMillis(); + for(int i = 0; i < 1000000; i++) { + long now = System.currentTimeMillis(); + String instant = Times.formatISO8601Instant(now); + long epoch = Times.parseISO8601ToLocalTimeInMillis(instant); + if (now != epoch) { + System.out.println(now); + System.out.println(epoch); + throw new IOException("millis different"); + } + } + long end = System.currentTimeMillis(); + System.out.println(end - start); + } + @Test + public void TimesCompareISO() throws IOException { + long start = System.currentTimeMillis(); + long sum = 0; + for(int i = 0; i < 1000000; i++) { + long now = System.currentTimeMillis(); + String instant = Times.formatISO8601Instant(now); + String date = Times.formatISO8601(now); + if (!date.equals(instant)) { + System.out.println(date); + System.out.println(instant); + throw new IOException("not equal"); + } + } + long end = System.currentTimeMillis(); + System.out.println(end - start); + System.out.println(sum); + } } \ No newline at end of file