TimestampRangePredicate: Use Instant instead of obsolete Date class

Note that we cannot use Instant.MIN/MAX to represent min/max timestamps
since this leads to "java.lang.ArithmeticException: long overflow" when
invoking Instant.toEpochMilli(). This is why we use
Instant.ofEpochMillis(0) and Instant.ofEpochMilli(Long.MAX_VALUE) to
represent min/max instead (the same way as it was done so far).

This change is a preparation for being able to enable the error level
for the JdkObsolete bug pattern in ErrorProne later.

Bug: Issue 15070
Signed-off-by: Edwin Kempin <ekempin@google.com>
Change-Id: Ia64a599440001071b8ddcca864cb6c86fc831c54
diff --git a/java/com/google/gerrit/elasticsearch/ElasticQueryBuilder.java b/java/com/google/gerrit/elasticsearch/ElasticQueryBuilder.java
index 40ac603..3eaf708 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticQueryBuilder.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticQueryBuilder.java
@@ -119,9 +119,9 @@
   }
 
   private <T> QueryBuilder notTimestamp(TimestampRangePredicate<T> r) throws QueryParseException {
-    if (r.getMinTimestamp().getTime() == 0) {
+    if (r.getMinTimestamp().toEpochMilli() == 0) {
       return QueryBuilders.rangeQuery(r.getField().getName())
-          .gt(Instant.ofEpochMilli(r.getMaxTimestamp().getTime()));
+          .gt(Instant.ofEpochMilli(r.getMaxTimestamp().toEpochMilli()));
     }
     throw new QueryParseException("cannot negate: " + r);
   }
@@ -129,15 +129,15 @@
   private <T> QueryBuilder timestampQuery(IndexPredicate<T> p) throws QueryParseException {
     if (p instanceof TimestampRangePredicate) {
       TimestampRangePredicate<T> r = (TimestampRangePredicate<T>) p;
-      if (r.getMaxTimestamp().getTime() == Long.MAX_VALUE) {
+      if (r.getMaxTimestamp().toEpochMilli() == Long.MAX_VALUE) {
         // The time range only has the start value, search from the start to the max supported value
         // Long.MAX_VALUE
         return QueryBuilders.rangeQuery(r.getField().getName())
-            .gte(Instant.ofEpochMilli(r.getMinTimestamp().getTime()));
+            .gte(Instant.ofEpochMilli(r.getMinTimestamp().toEpochMilli()));
       }
       return QueryBuilders.rangeQuery(r.getField().getName())
-          .gte(Instant.ofEpochMilli(r.getMinTimestamp().getTime()))
-          .lte(Instant.ofEpochMilli(r.getMaxTimestamp().getTime()));
+          .gte(Instant.ofEpochMilli(r.getMinTimestamp().toEpochMilli()))
+          .lte(Instant.ofEpochMilli(r.getMaxTimestamp().toEpochMilli()));
     }
     throw new QueryParseException("not a timestamp: " + p);
   }
diff --git a/java/com/google/gerrit/index/query/TimestampRangePredicate.java b/java/com/google/gerrit/index/query/TimestampRangePredicate.java
index 42f8aa8..29d6f22 100644
--- a/java/com/google/gerrit/index/query/TimestampRangePredicate.java
+++ b/java/com/google/gerrit/index/query/TimestampRangePredicate.java
@@ -17,13 +17,13 @@
 import com.google.gerrit.index.FieldDef;
 import com.google.gerrit.json.JavaSqlTimestampHelper;
 import java.sql.Timestamp;
-import java.util.Date;
+import java.time.Instant;
 
 // TODO: Migrate this to IntegerRangePredicate
 public abstract class TimestampRangePredicate<I> extends IndexPredicate<I> {
-  protected static Timestamp parse(String value) throws QueryParseException {
+  protected static Instant parse(String value) throws QueryParseException {
     try {
-      return JavaSqlTimestampHelper.parseTimestamp(value);
+      return JavaSqlTimestampHelper.parseTimestamp(value).toInstant();
     } catch (IllegalArgumentException e) {
       // parseTimestamp's errors are specific and helpful, so preserve them.
       throw new QueryParseException(e.getMessage(), e);
@@ -38,7 +38,7 @@
     return (Timestamp) this.getField().get(object);
   }
 
-  public abstract Date getMinTimestamp();
+  public abstract Instant getMinTimestamp();
 
-  public abstract Date getMaxTimestamp();
+  public abstract Instant getMaxTimestamp();
 }
diff --git a/java/com/google/gerrit/lucene/QueryBuilder.java b/java/com/google/gerrit/lucene/QueryBuilder.java
index 9432abd..e1b56c6 100644
--- a/java/com/google/gerrit/lucene/QueryBuilder.java
+++ b/java/com/google/gerrit/lucene/QueryBuilder.java
@@ -231,15 +231,17 @@
     if (p instanceof TimestampRangePredicate) {
       TimestampRangePredicate<V> r = (TimestampRangePredicate<V>) p;
       return longRangeQuery.get(
-          r.getField().getName(), r.getMinTimestamp().getTime(), r.getMaxTimestamp().getTime());
+          r.getField().getName(),
+          r.getMinTimestamp().toEpochMilli(),
+          r.getMaxTimestamp().toEpochMilli());
     }
     throw new QueryParseException("not a timestamp: " + p);
   }
 
   private Query notTimestamp(TimestampRangePredicate<V> r) throws QueryParseException {
-    if (r.getMinTimestamp().getTime() == 0) {
+    if (r.getMinTimestamp().toEpochMilli() == 0) {
       return longRangeQuery.get(
-          r.getField().getName(), r.getMaxTimestamp().getTime(), Long.MAX_VALUE);
+          r.getField().getName(), r.getMaxTimestamp().toEpochMilli(), Long.MAX_VALUE);
     }
     throw new QueryParseException("cannot negate: " + r);
   }
diff --git a/java/com/google/gerrit/server/query/change/AfterPredicate.java b/java/com/google/gerrit/server/query/change/AfterPredicate.java
index 8f92d9a..2514989 100644
--- a/java/com/google/gerrit/server/query/change/AfterPredicate.java
+++ b/java/com/google/gerrit/server/query/change/AfterPredicate.java
@@ -17,14 +17,14 @@
 import com.google.gerrit.index.FieldDef;
 import com.google.gerrit.index.query.QueryParseException;
 import java.sql.Timestamp;
-import java.util.Date;
+import java.time.Instant;
 
 /**
  * Predicate that matches a {@link Timestamp} field from the index in a range from the passed {@code
  * String} representation of the Timestamp value to the maximum supported time.
  */
 public class AfterPredicate extends TimestampRangeChangePredicate {
-  protected final Date cut;
+  protected final Instant cut;
 
   public AfterPredicate(FieldDef<ChangeData, Timestamp> def, String name, String value)
       throws QueryParseException {
@@ -33,13 +33,13 @@
   }
 
   @Override
-  public Date getMinTimestamp() {
+  public Instant getMinTimestamp() {
     return cut;
   }
 
   @Override
-  public Date getMaxTimestamp() {
-    return new Date(Long.MAX_VALUE);
+  public Instant getMaxTimestamp() {
+    return Instant.ofEpochMilli(Long.MAX_VALUE);
   }
 
   @Override
@@ -48,6 +48,6 @@
     if (valueTimestamp == null) {
       return false;
     }
-    return valueTimestamp.getTime() >= cut.getTime();
+    return valueTimestamp.getTime() >= cut.toEpochMilli();
   }
 }
diff --git a/java/com/google/gerrit/server/query/change/AgePredicate.java b/java/com/google/gerrit/server/query/change/AgePredicate.java
index d38789f..d2c6e6f 100644
--- a/java/com/google/gerrit/server/query/change/AgePredicate.java
+++ b/java/com/google/gerrit/server/query/change/AgePredicate.java
@@ -21,26 +21,27 @@
 import com.google.gerrit.server.index.change.ChangeField;
 import com.google.gerrit.server.util.time.TimeUtil;
 import java.sql.Timestamp;
+import java.time.Instant;
 
 public class AgePredicate extends TimestampRangeChangePredicate {
-  protected final long cut;
+  protected final Instant cut;
 
   public AgePredicate(String value) {
     super(ChangeField.UPDATED, ChangeQueryBuilder.FIELD_AGE, value);
 
     long s = ConfigUtil.getTimeUnit(getValue(), 0, SECONDS);
     long ms = MILLISECONDS.convert(s, SECONDS);
-    this.cut = TimeUtil.nowMs() - ms;
+    this.cut = Instant.ofEpochMilli(TimeUtil.nowMs() - ms);
   }
 
   @Override
-  public Timestamp getMinTimestamp() {
-    return new Timestamp(0);
+  public Instant getMinTimestamp() {
+    return Instant.ofEpochMilli(0);
   }
 
   @Override
-  public Timestamp getMaxTimestamp() {
-    return new Timestamp(cut);
+  public Instant getMaxTimestamp() {
+    return cut;
   }
 
   @Override
@@ -49,6 +50,6 @@
     if (valueTimestamp == null) {
       return false;
     }
-    return valueTimestamp.getTime() <= cut;
+    return valueTimestamp.getTime() <= cut.toEpochMilli();
   }
 }
diff --git a/java/com/google/gerrit/server/query/change/BeforePredicate.java b/java/com/google/gerrit/server/query/change/BeforePredicate.java
index 6e28ce6..61bf6b1 100644
--- a/java/com/google/gerrit/server/query/change/BeforePredicate.java
+++ b/java/com/google/gerrit/server/query/change/BeforePredicate.java
@@ -17,14 +17,14 @@
 import com.google.gerrit.index.FieldDef;
 import com.google.gerrit.index.query.QueryParseException;
 import java.sql.Timestamp;
-import java.util.Date;
+import java.time.Instant;
 
 /**
  * Predicate that matches a {@link Timestamp} field from the index in a range from the the epoch to
  * the passed {@code String} representation of the Timestamp value.
  */
 public class BeforePredicate extends TimestampRangeChangePredicate {
-  protected final Date cut;
+  protected final Instant cut;
 
   public BeforePredicate(FieldDef<ChangeData, Timestamp> def, String name, String value)
       throws QueryParseException {
@@ -33,12 +33,12 @@
   }
 
   @Override
-  public Date getMinTimestamp() {
-    return new Date(0);
+  public Instant getMinTimestamp() {
+    return Instant.ofEpochMilli(0);
   }
 
   @Override
-  public Date getMaxTimestamp() {
+  public Instant getMaxTimestamp() {
     return cut;
   }
 
@@ -48,6 +48,6 @@
     if (valueTimestamp == null) {
       return false;
     }
-    return valueTimestamp.getTime() <= cut.getTime();
+    return valueTimestamp.getTime() <= cut.toEpochMilli();
   }
 }