1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 package com.google.protobuf.util;
33 import com.google.protobuf.Duration;
34 import com.google.protobuf.Timestamp;
36 import java.math.BigInteger;
37 import java.text.ParseException;
40 * Utilities to help create/manipulate Timestamp/Duration
42 * @deprecated Use {@link Durations} and {@link Timestamps} instead.
45 public final class TimeUtil {
46 // Timestamp for "0001-01-01T00:00:00Z"
47 public static final long TIMESTAMP_SECONDS_MIN = -62135596800L;
49 // Timestamp for "9999-12-31T23:59:59Z"
50 public static final long TIMESTAMP_SECONDS_MAX = 253402300799L;
51 public static final long DURATION_SECONDS_MIN = -315576000000L;
52 public static final long DURATION_SECONDS_MAX = 315576000000L;
54 private static final long NANOS_PER_SECOND = 1000000000;
59 * Convert Timestamp to RFC 3339 date string format. The output will always
60 * be Z-normalized and uses 3, 6 or 9 fractional digits as required to
61 * represent the exact value. Note that Timestamp can only represent time
62 * from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. See
63 * https://www.ietf.org/rfc/rfc3339.txt
65 * <p>Example of generated format: "1972-01-01T10:00:20.021Z"
67 * @return The string representation of the given timestamp.
68 * @throws IllegalArgumentException if the given timestamp is not in the
70 * @deprecated Use {@link Timestamps#toString} instead.
73 public static String toString(Timestamp timestamp) {
74 return Timestamps.toString(timestamp);
78 * Parse from RFC 3339 date string to Timestamp. This method accepts all
79 * outputs of {@link #toString(Timestamp)} and it also accepts any fractional
80 * digits (or none) and any offset as long as they fit into nano-seconds
83 * <p>Example of accepted format: "1972-01-01T10:00:20.021-05:00"
85 * @return A Timestamp parsed from the string.
86 * @throws ParseException if parsing fails.
87 * @deprecated Use {@link Timestamps#parse} instead.
90 public static Timestamp parseTimestamp(String value) throws ParseException {
91 return Timestamps.parse(value);
95 * Convert Duration to string format. The string format will contains 3, 6,
96 * or 9 fractional digits depending on the precision required to represent
97 * the exact Duration value. For example: "1s", "1.010s", "1.000000100s",
98 * "-3.100s" The range that can be represented by Duration is from
99 * -315,576,000,000 to +315,576,000,000 inclusive (in seconds).
101 * @return The string representation of the given duration.
102 * @throws IllegalArgumentException if the given duration is not in the valid
104 * @deprecated Use {@link Durations#toString} instead.
107 public static String toString(Duration duration) {
108 return Durations.toString(duration);
112 * Parse from a string to produce a duration.
114 * @return A Duration parsed from the string.
115 * @throws ParseException if parsing fails.
116 * @deprecated Use {@link Durations#parse} instead.
119 public static Duration parseDuration(String value) throws ParseException {
120 return Durations.parse(value);
124 * Create a Timestamp from the number of milliseconds elapsed from the epoch.
126 * @deprecated Use {@link Timestamps#fromMillis} instead.
129 public static Timestamp createTimestampFromMillis(long milliseconds) {
130 return Timestamps.fromMillis(milliseconds);
134 * Create a Duration from the number of milliseconds.
136 * @deprecated Use {@link Durations#fromMillis} instead.
139 public static Duration createDurationFromMillis(long milliseconds) {
140 return Durations.fromMillis(milliseconds);
144 * Convert a Timestamp to the number of milliseconds elapsed from the epoch.
146 * <p>The result will be rounded down to the nearest millisecond. E.g., if the
147 * timestamp represents "1969-12-31T23:59:59.999999999Z", it will be rounded
150 * @deprecated Use {@link Timestamps#toMillis} instead.
153 public static long toMillis(Timestamp timestamp) {
154 return Timestamps.toMillis(timestamp);
158 * Convert a Duration to the number of milliseconds.The result will be
159 * rounded towards 0 to the nearest millisecond. E.g., if the duration
160 * represents -1 nanosecond, it will be rounded to 0.
162 * @deprecated Use {@link Durations#toMillis} instead.
165 public static long toMillis(Duration duration) {
166 return Durations.toMillis(duration);
170 * Create a Timestamp from the number of microseconds elapsed from the epoch.
172 * @deprecated Use {@link Timestamps#fromMicros} instead.
175 public static Timestamp createTimestampFromMicros(long microseconds) {
176 return Timestamps.fromMicros(microseconds);
180 * Create a Duration from the number of microseconds.
182 * @deprecated Use {@link Durations#fromMicros} instead.
185 public static Duration createDurationFromMicros(long microseconds) {
186 return Durations.fromMicros(microseconds);
190 * Convert a Timestamp to the number of microseconds elapsed from the epoch.
192 * <p>The result will be rounded down to the nearest microsecond. E.g., if the
193 * timestamp represents "1969-12-31T23:59:59.999999999Z", it will be rounded
196 * @deprecated Use {@link Timestamps#toMicros} instead.
199 public static long toMicros(Timestamp timestamp) {
200 return Timestamps.toMicros(timestamp);
204 * Convert a Duration to the number of microseconds.The result will be
205 * rounded towards 0 to the nearest microseconds. E.g., if the duration
206 * represents -1 nanosecond, it will be rounded to 0.
208 * @deprecated Use {@link Durations#toMicros} instead.
211 public static long toMicros(Duration duration) {
212 return Durations.toMicros(duration);
216 * Create a Timestamp from the number of nanoseconds elapsed from the epoch.
218 * @deprecated Use {@link Timestamps#fromNanos} instead.
221 public static Timestamp createTimestampFromNanos(long nanoseconds) {
222 return Timestamps.fromNanos(nanoseconds);
226 * Create a Duration from the number of nanoseconds.
228 * @deprecated Use {@link Durations#fromNanos} instead.
231 public static Duration createDurationFromNanos(long nanoseconds) {
232 return Durations.fromNanos(nanoseconds);
236 * Convert a Timestamp to the number of nanoseconds elapsed from the epoch.
238 * @deprecated Use {@link Timestamps#toNanos} instead.
241 public static long toNanos(Timestamp timestamp) {
242 return Timestamps.toNanos(timestamp);
246 * Convert a Duration to the number of nanoseconds.
248 * @deprecated Use {@link Durations#toNanos} instead.
251 public static long toNanos(Duration duration) {
252 return Durations.toNanos(duration);
256 * Get the current time.
258 * @deprecated Use {@code Timestamps.fromMillis(System.currentTimeMillis())} instead.
261 public static Timestamp getCurrentTime() {
262 return Timestamps.fromMillis(System.currentTimeMillis());
268 * @deprecated Use {@code Timestamps.fromMillis(0)} instead.
271 public static Timestamp getEpoch() {
272 return Timestamp.getDefaultInstance();
276 * Calculate the difference between two timestamps.
278 * @deprecated Use {@link Timestamps#between} instead.
281 public static Duration distance(Timestamp from, Timestamp to) {
282 return Timestamps.between(from, to);
286 * Add a duration to a timestamp.
288 * @deprecated Use {@link Timestamps#add} instead.
291 public static Timestamp add(Timestamp start, Duration length) {
292 return Timestamps.add(start, length);
296 * Subtract a duration from a timestamp.
298 * @deprecated Use {@link Timestamps#subtract} instead.
301 public static Timestamp subtract(Timestamp start, Duration length) {
302 return Timestamps.subtract(start, length);
308 * @deprecated Use {@link Durations#add} instead.
311 public static Duration add(Duration d1, Duration d2) {
312 return Durations.add(d1, d2);
316 * Subtract a duration from another.
318 * @deprecated Use {@link Durations#subtract} instead.
321 public static Duration subtract(Duration d1, Duration d2) {
322 return Durations.subtract(d1, d2);
325 // Multiplications and divisions.
327 // TODO(kak): Delete this.
328 @SuppressWarnings("DurationSecondsToDouble")
329 public static Duration multiply(Duration duration, double times) {
330 double result = duration.getSeconds() * times + duration.getNanos() * times / 1000000000.0;
331 if (result < Long.MIN_VALUE || result > Long.MAX_VALUE) {
332 throw new IllegalArgumentException("Result is out of valid range.");
334 long seconds = (long) result;
335 int nanos = (int) ((result - seconds) * 1000000000);
336 return normalizedDuration(seconds, nanos);
339 // TODO(kak): Delete this.
340 public static Duration divide(Duration duration, double value) {
341 return multiply(duration, 1.0 / value);
344 // TODO(kak): Delete this.
345 public static Duration multiply(Duration duration, long times) {
346 return createDurationFromBigInteger(toBigInteger(duration).multiply(toBigInteger(times)));
349 // TODO(kak): Delete this.
350 public static Duration divide(Duration duration, long times) {
351 return createDurationFromBigInteger(toBigInteger(duration).divide(toBigInteger(times)));
354 // TODO(kak): Delete this.
355 public static long divide(Duration d1, Duration d2) {
356 return toBigInteger(d1).divide(toBigInteger(d2)).longValue();
359 // TODO(kak): Delete this.
360 public static Duration remainder(Duration d1, Duration d2) {
361 return createDurationFromBigInteger(toBigInteger(d1).remainder(toBigInteger(d2)));
364 private static final BigInteger NANOS_PER_SECOND_BIG_INTEGER =
365 new BigInteger(String.valueOf(NANOS_PER_SECOND));
367 private static BigInteger toBigInteger(Duration duration) {
368 return toBigInteger(duration.getSeconds())
369 .multiply(NANOS_PER_SECOND_BIG_INTEGER)
370 .add(toBigInteger(duration.getNanos()));
373 private static BigInteger toBigInteger(long value) {
374 return new BigInteger(String.valueOf(value));
377 private static Duration createDurationFromBigInteger(BigInteger value) {
378 long seconds = value.divide(new BigInteger(String.valueOf(NANOS_PER_SECOND))).longValue();
379 int nanos = value.remainder(new BigInteger(String.valueOf(NANOS_PER_SECOND))).intValue();
380 return normalizedDuration(seconds, nanos);
383 private static Duration normalizedDuration(long seconds, int nanos) {
384 if (nanos <= -NANOS_PER_SECOND || nanos >= NANOS_PER_SECOND) {
385 seconds += nanos / NANOS_PER_SECOND;
386 nanos %= NANOS_PER_SECOND;
388 if (seconds > 0 && nanos < 0) {
389 nanos += NANOS_PER_SECOND;
392 if (seconds < 0 && nanos > 0) {
393 nanos -= NANOS_PER_SECOND;
396 if (seconds < DURATION_SECONDS_MIN || seconds > DURATION_SECONDS_MAX) {
397 throw new IllegalArgumentException("Duration is out of valid range.");
399 return Duration.newBuilder().setSeconds(seconds).setNanos(nanos).build();