Selaa lähdekoodia

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 d4a91bd0c0d9d438ffe95fafee0212499b0abcfd)
jteagles 3 vuotta sitten
vanhempi
commit
6daa369bcf

+ 13 - 20
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/Times.java

@@ -19,8 +19,9 @@
 package org.apache.hadoop.yarn.util;
 
 import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -30,23 +31,16 @@ import org.apache.hadoop.classification.InterfaceAudience.Private;
 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";
 
   // This format should match the one used in yarn.dt.plugins.js
-  static final ThreadLocal<SimpleDateFormat> dateFormat =
-      new ThreadLocal<SimpleDateFormat>() {
-        @Override protected SimpleDateFormat initialValue() {
-          return new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy");
-        }
-      };
+  static final DateTimeFormatter DATE_FORMAT =
+      DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss Z yyyy").withZone(
+          ZoneId.systemDefault());
 
-  static final ThreadLocal<SimpleDateFormat> isoFormat =
-      new ThreadLocal<SimpleDateFormat>() {
-        @Override
-        protected SimpleDateFormat initialValue() {
-          return new SimpleDateFormat(ISO8601DATEFORMAT);
-        }
-      };
+  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);
@@ -82,8 +76,7 @@ public class Times {
   }
 
   public static String format(long ts) {
-    return ts > 0 ? String.valueOf(dateFormat.get().format(new Date(ts)))
-                  : "N/A";
+    return ts > 0 ? DATE_FORMAT.format(Instant.ofEpochMilli(ts)) : "N/A";
   }
 
   /**
@@ -93,7 +86,7 @@ public class Times {
    * @return ISO 8601 formatted string.
    */
   public static String formatISO8601(long ts) {
-    return isoFormat.get().format(new Date(ts));
+    return ISO_OFFSET_DATE_TIME.format(Instant.ofEpochMilli(ts));
   }
 
   /**
@@ -108,6 +101,6 @@ public class Times {
     if (isoString == null) {
       throw new ParseException("Invalid input.", -1);
     }
-    return isoFormat.get().parse(isoString).getTime();
+    return Instant.from(ISO_OFFSET_DATE_TIME.parse(isoString)).toEpochMilli();
   }
 }

+ 17 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/util/TestTimes.java

@@ -21,6 +21,12 @@ package org.apache.hadoop.yarn.util;
 import org.junit.Assert;
 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 {
 
   @Test
@@ -61,4 +67,15 @@ public class TestTimes {
     elapsed = Times.elapsed(Long.MAX_VALUE, 0, true);
     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);
+    }
+  }
 }