aboutsummaryrefslogtreecommitdiff
path: root/java/util/src/main/java/com/google/protobuf/util/Timestamps.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/util/src/main/java/com/google/protobuf/util/Timestamps.java')
-rw-r--r--java/util/src/main/java/com/google/protobuf/util/Timestamps.java45
1 files changed, 31 insertions, 14 deletions
diff --git a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java
index 2160e4d5..9e528d4a 100644
--- a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java
+++ b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java
@@ -30,7 +30,6 @@
package com.google.protobuf.util;
-import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.math.IntMath.checkedAdd;
import static com.google.common.math.IntMath.checkedSubtract;
import static com.google.common.math.LongMath.checkedAdd;
@@ -44,6 +43,7 @@ import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.GregorianCalendar;
+import java.util.Locale;
import java.util.TimeZone;
/**
@@ -74,6 +74,11 @@ public final class Timestamps {
public static final Timestamp MAX_VALUE =
Timestamp.newBuilder().setSeconds(TIMESTAMP_SECONDS_MAX).setNanos(999999999).build();
+ /**
+ * A constant holding the {@link Timestamp} of epoch time, {@code 1970-01-01T00:00:00.000000000Z}.
+ */
+ public static final Timestamp EPOCH = Timestamp.newBuilder().setSeconds(0).setNanos(0).build();
+
private static final ThreadLocal<SimpleDateFormat> timestampFormat =
new ThreadLocal<SimpleDateFormat>() {
@Override
@@ -83,7 +88,7 @@ public final class Timestamps {
};
private static SimpleDateFormat createTimestampFormat() {
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH);
GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
// We use Proleptic Gregorian Calendar (i.e., Gregorian calendar extends
// backwards to year one) for timestamp formating.
@@ -114,6 +119,17 @@ public final class Timestamps {
}
/**
+ * Compares two timestamps. The value returned is identical to what would be returned by:
+ * {@code Timestamps.comparator().compare(x, y)}.
+ *
+ * @return the value {@code 0} if {@code x == y}; a value less than {@code 0} if {@code x < y};
+ * and a value greater than {@code 0} if {@code x > y}
+ */
+ public static int compare(Timestamp x, Timestamp y) {
+ return COMPARATOR.compare(x, y);
+ }
+
+ /**
* Returns true if the given {@link Timestamp} is valid. The {@code seconds} value must be in the
* range [-62,135,596,800, +253,402,300,799] (i.e., between 0001-01-01T00:00:00Z and
* 9999-12-31T23:59:59Z). The {@code nanos} value must be in the range [0, +999,999,999].
@@ -148,13 +164,12 @@ public final class Timestamps {
public static Timestamp checkValid(Timestamp timestamp) {
long seconds = timestamp.getSeconds();
int nanos = timestamp.getNanos();
- checkArgument(
- isValid(seconds, nanos),
- "Timestamp is not valid. See proto definition for valid values. "
+ if (!isValid(seconds, nanos)) {
+ throw new IllegalArgumentException(String.format(
+ "Timestamp is not valid. See proto definition for valid values. "
+ "Seconds (%s) must be in range [-62,135,596,800, +253,402,300,799]. "
- + "Nanos (%s) must be in range [0, +999,999,999].",
- seconds,
- nanos);
+ + "Nanos (%s) must be in range [0, +999,999,999].", seconds, nanos));
+ }
return timestamp;
}
@@ -296,7 +311,7 @@ public final class Timestamps {
* Convert a Timestamp to the number of microseconds elapsed from the epoch.
*
* <p>The result will be rounded down to the nearest microsecond. E.g., if the timestamp
- * represents "1969-12-31T23:59:59.999999999Z", it will be rounded to -1 millisecond.
+ * represents "1969-12-31T23:59:59.999999999Z", it will be rounded to -1 microsecond.
*/
public static long toMicros(Timestamp timestamp) {
checkValid(timestamp);
@@ -348,10 +363,12 @@ public final class Timestamps {
static Timestamp normalizedTimestamp(long seconds, int nanos) {
if (nanos <= -NANOS_PER_SECOND || nanos >= NANOS_PER_SECOND) {
seconds = checkedAdd(seconds, nanos / NANOS_PER_SECOND);
- nanos %= NANOS_PER_SECOND;
+ nanos = (int) (nanos % NANOS_PER_SECOND);
}
if (nanos < 0) {
- nanos += NANOS_PER_SECOND; // no overflow since nanos is negative (and we're adding)
+ nanos =
+ (int)
+ (nanos + NANOS_PER_SECOND); // no overflow since nanos is negative (and we're adding)
seconds = checkedSubtract(seconds, 1);
}
Timestamp timestamp = Timestamp.newBuilder().setSeconds(seconds).setNanos(nanos).build();
@@ -386,11 +403,11 @@ public final class Timestamps {
static String formatNanos(int nanos) {
// Determine whether to use 3, 6, or 9 digits for the nano part.
if (nanos % NANOS_PER_MILLISECOND == 0) {
- return String.format("%1$03d", nanos / NANOS_PER_MILLISECOND);
+ return String.format(Locale.ENGLISH, "%1$03d", nanos / NANOS_PER_MILLISECOND);
} else if (nanos % NANOS_PER_MICROSECOND == 0) {
- return String.format("%1$06d", nanos / NANOS_PER_MICROSECOND);
+ return String.format(Locale.ENGLISH, "%1$06d", nanos / NANOS_PER_MICROSECOND);
} else {
- return String.format("%1$09d", nanos);
+ return String.format(Locale.ENGLISH, "%1$09d", nanos);
}
}
}