diff --git a/core/src/main/java/hudson/Util.java b/core/src/main/java/hudson/Util.java
index 70267c2c27..4e2dc2bd4d 100644
--- a/core/src/main/java/hudson/Util.java
+++ b/core/src/main/java/hudson/Util.java
@@ -75,8 +75,8 @@ import java.security.NoSuchAlgorithmException;
import java.text.NumberFormat;
import java.text.ParseException;
import java.time.LocalDate;
-import java.time.Period;
import java.time.ZoneId;
+import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -92,10 +92,6 @@ import javax.annotation.Nullable;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.commons.io.FileUtils;
-
-import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;
/**
@@ -1672,18 +1668,19 @@ public class Util {
* even if there are only 3 hours between. As well as "10am" to "2pm" both on the same day, returns 0.
*/
@Restricted(NoExternalUse.class)
- public static int differenceInCalendarDay(@Nonnull Date a, @Nonnull Date b){
+ public static long daysBetween(@Nonnull Date a, @Nonnull Date b){
LocalDate aLocal = a.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate bLocal = b.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
- return Period.between(aLocal, bLocal).getDays();
+ return ChronoUnit.DAYS.between(aLocal, bLocal);
}
/**
- * @see #differenceInCalendarDay(Date, Date)
+ * @return positive number of days between the given date and now
+ * @see #daysBetween(Date, Date)
*/
@Restricted(NoExternalUse.class)
- public static int numOfCalendarDayToNow(@Nonnull Date date){
- return differenceInCalendarDay(date, new Date());
+ public static long daysElapsedSince(@Nonnull Date date){
+ return Math.max(0, daysBetween(date, new Date()));
}
public static final FastDateFormat XS_DATETIME_FORMATTER = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss'Z'",new SimpleTimeZone(0,"GMT"));
diff --git a/core/src/main/java/jenkins/security/apitoken/ApiTokenStats.java b/core/src/main/java/jenkins/security/apitoken/ApiTokenStats.java
index 91594b18e7..f92fd8e701 100644
--- a/core/src/main/java/jenkins/security/apitoken/ApiTokenStats.java
+++ b/core/src/main/java/jenkins/security/apitoken/ApiTokenStats.java
@@ -34,12 +34,6 @@ import org.kohsuke.accmod.restrictions.NoExternalUse;
import javax.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
-import java.time.Duration;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.Period;
-import java.time.ZoneId;
-import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
@@ -256,7 +250,7 @@ public class ApiTokenStats implements Saveable {
* Relevant only if the lastUseDate is not null
*/
public long getNumDaysUse() {
- return lastUseDate == null ? 0 : Math.max(0, Util.numOfCalendarDayToNow(lastUseDate));
+ return lastUseDate == null ? 0 : Util.daysElapsedSince(lastUseDate);
}
}
}
diff --git a/core/src/main/java/jenkins/security/apitoken/ApiTokenStore.java b/core/src/main/java/jenkins/security/apitoken/ApiTokenStore.java
index c4d2dc2cae..29d99120ec 100644
--- a/core/src/main/java/jenkins/security/apitoken/ApiTokenStore.java
+++ b/core/src/main/java/jenkins/security/apitoken/ApiTokenStore.java
@@ -40,8 +40,6 @@ import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
-import java.time.Instant;
-import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
@@ -420,7 +418,7 @@ public class ApiTokenStore {
* Relevant only if the lastUseDate is not null
*/
public long getNumDaysCreation() {
- return creationDate == null ? 0 : Math.max(0, Util.numOfCalendarDayToNow(creationDate));
+ return creationDate == null ? 0 : Util.daysElapsedSince(creationDate);
}
// used by Jelly view
diff --git a/core/src/main/resources/jenkins/security/ApiTokenProperty/config.jelly b/core/src/main/resources/jenkins/security/ApiTokenProperty/config.jelly
index d1cb2c203b..b7aee62ac7 100644
--- a/core/src/main/resources/jenkins/security/ApiTokenProperty/config.jelly
+++ b/core/src/main/resources/jenkins/security/ApiTokenProperty/config.jelly
@@ -59,11 +59,14 @@ THE SOFTWARE.
-
+
+
+
+
- ${%TokenCreation(daysOld)}
+ ${creationDateValue}
@@ -71,13 +74,18 @@ THE SOFTWARE.
-
+
+
+
+ ${%TokenNeverUsedValue}
+
+
+
+ ${%TokenLastUse(useCounter, token.numDaysUse)}
+
-
- ${%TokenLastUse(useCounter, token.numDaysUse)}
-
diff --git a/core/src/main/resources/jenkins/security/ApiTokenProperty/config.properties b/core/src/main/resources/jenkins/security/ApiTokenProperty/config.properties
index fc6b26c4d7..79bef819d2 100644
--- a/core/src/main/resources/jenkins/security/ApiTokenProperty/config.properties
+++ b/core/src/main/resources/jenkins/security/ApiTokenProperty/config.properties
@@ -6,6 +6,7 @@ TokenLastUse=Used {0} time(s), last time was {1} day(s) ago
StatisticsDisabled=No statistics available
StatisticsDisabled.Title=Token usage statistics are currently disabled
TokenNeverUsed=Never used
+TokenNeverUsedTooltip=There is no last use date for that token
TokenNeverUsed.Title=We strongly recommend that you revoke tokens which you do not plan to use
ConfirmRevokeSingle=Are you sure you want to revoke this token ? Applications that are using it will be not able to connect anymore.
CurrentTokens=Current token(s)
@@ -13,3 +14,5 @@ TokenCreation=Created {0} day(s) ago
RenameToken=Save the new name of the token
LegacyToken=We strongly recommend that you revoke this legacy token and replace it with a newly generated token for increased security.
NoLegacyToken=The user does not have a legacy token
+NoCreationDate=There is no creation date for that token
+NoCreationDateValue=Unknown
diff --git a/core/src/test/java/hudson/UtilTest.java b/core/src/test/java/hudson/UtilTest.java
index 3bc278a164..11a057b65e 100644
--- a/core/src/test/java/hudson/UtilTest.java
+++ b/core/src/test/java/hudson/UtilTest.java
@@ -61,7 +61,6 @@ import org.jvnet.hudson.test.Issue;
import hudson.util.StreamTaskListener;
import org.junit.Rule;
-import org.junit.internal.AssumptionViolatedException;
import org.junit.rules.TemporaryFolder;
import com.google.common.collect.Lists;
@@ -784,18 +783,27 @@ public class UtilTest {
@Test
public void testDifferenceDays() {
- Date day1_10am = new Date(2018, 4, 6, 10, 0);
- Date day1_11pm55 = new Date(2018, 4, 6, 23, 55);
- Date day2_01am = new Date(2018, 4, 7, 1, 0);
- Date day2_11pm = new Date(2018, 4, 7, 1, 0);
- Date day3_08am = new Date(2018, 4, 8, 8, 0);
- assertEquals(0, Util.differenceInCalendarDay(day1_10am, day1_11pm55));
- assertEquals(1, Util.differenceInCalendarDay(day1_10am, day2_01am));
- assertEquals(1, Util.differenceInCalendarDay(day1_11pm55, day2_01am));
- assertEquals(2, Util.differenceInCalendarDay(day1_10am, day3_08am));
- assertEquals(1, Util.differenceInCalendarDay(day2_11pm, day3_08am));
+ Date may_6_10am = new Date(2018 - 1900, 4, 6, 10, 0);
+ Date may_6_11pm55 = new Date(2018 - 1900, 4, 6, 23, 55);
+ Date may_7_01am = new Date(2018 - 1900, 4, 7, 1, 0);
+ Date may_7_11pm = new Date(2018 - 1900, 4, 7, 1, 0);
+ Date may_8_08am = new Date(2018 - 1900, 4, 8, 8, 0);
+ Date june_3_08am = new Date(2018 - 1900, 5, 3, 8, 0);
+ Date june_9_08am = new Date(2018 - 1900, 5, 9, 8, 0);
+ Date june_9_08am_nextYear = new Date(2019 - 1900, 5, 9, 8, 0);
+
+ assertEquals(0, Util.daysBetween(may_6_10am, may_6_11pm55));
+ assertEquals(1, Util.daysBetween(may_6_10am, may_7_01am));
+ assertEquals(1, Util.daysBetween(may_6_11pm55, may_7_01am));
+ assertEquals(2, Util.daysBetween(may_6_10am, may_8_08am));
+ assertEquals(1, Util.daysBetween(may_7_11pm, may_8_08am));
+
+ // larger scale
+ assertEquals(28, Util.daysBetween(may_6_10am, june_3_08am));
+ assertEquals(34, Util.daysBetween(may_6_10am, june_9_08am));
+ assertEquals(365 + 34, Util.daysBetween(may_6_10am, june_9_08am_nextYear));
// reverse order
- assertEquals(-1, Util.differenceInCalendarDay(day3_08am, day2_11pm));
+ assertEquals(-1, Util.daysBetween(may_8_08am, may_7_11pm));
}
}