1818
1919import static com .google .common .base .Preconditions .checkArgument ;
2020
21- import com .google .common .base .Strings ;
2221import com .google .protobuf .util .Timestamps ;
2322import java .io .Serializable ;
2423import java .util .Date ;
2524import java .util .Objects ;
2625import java .util .concurrent .TimeUnit ;
27- import java . util . regex . Matcher ;
28- import java . util . regex . Pattern ;
29- import org .joda . time . chrono . GregorianChronology ;
30- import org .joda . time . format . DateTimeFormatter ;
31- import org .joda . time .format .ISODateTimeFormat ;
26+ import org . threeten . bp . Instant ;
27+ import org . threeten . bp . LocalDateTime ;
28+ import org .threeten . bp . ZoneOffset ;
29+ import org .threeten . bp . chrono . IsoChronology ;
30+ import org .threeten . bp .format .DateTimeFormatter ;
3231
3332/**
34- * Represents a timestamp with nanosecond precision. Timestamps cover the range
35- * [0001-01-01, 9999-12-31].
33+ * Represents a timestamp with nanosecond precision. Timestamps cover the range [0001-01-01,
34+ * 9999-12-31].
3635 *
3736 * <p>{@code Timestamp} instances are immutable.
3837 */
@@ -47,13 +46,8 @@ public final class Timestamp implements Comparable<Timestamp>, Serializable {
4746 public static final Timestamp MAX_VALUE =
4847 new Timestamp (253402300799L , (int ) TimeUnit .SECONDS .toNanos (1 ) - 1 );
4948
50- /** Regexp to split timestamps into date-hour-minute-second and fractional second components. */
51- private static final Pattern FORMAT_REGEXP = Pattern .compile ("([^\\ .]*)(\\ .\\ d{0,9})?Z" );
52-
53- private static final long NANOS_PER_SECOND = TimeUnit .SECONDS .toNanos (1 );
54-
5549 private static final DateTimeFormatter format =
56- ISODateTimeFormat . dateHourMinuteSecond () .withChronology (GregorianChronology . getInstanceUTC () );
50+ DateTimeFormatter . ISO_LOCAL_DATE_TIME .withChronology (IsoChronology . INSTANCE );
5751
5852 private final long seconds ;
5953 private final int nanos ;
@@ -85,8 +79,8 @@ public static Timestamp ofTimeSecondsAndNanos(long seconds, int nanos) {
8579 */
8680 public static Timestamp ofTimeMicroseconds (long microseconds ) {
8781 long seconds = TimeUnit .MICROSECONDS .toSeconds (microseconds );
88- int nanos = ( int ) TimeUnit . MICROSECONDS . toNanos (
89- microseconds - TimeUnit .SECONDS .toMicros (seconds ));
82+ int nanos =
83+ ( int ) TimeUnit . MICROSECONDS . toNanos ( microseconds - TimeUnit .SECONDS .toMicros (seconds ));
9084 checkArgument (
9185 Timestamps .isValid (seconds , nanos ), "timestamp out of range: %s, %s" , seconds , nanos );
9286 return new Timestamp (seconds , nanos );
@@ -101,10 +95,7 @@ public static Timestamp of(Date date) {
10195 return ofTimeMicroseconds (TimeUnit .MILLISECONDS .toMicros (date .getTime ()));
10296 }
10397
104-
105- /**
106- * Creates an instance with current time.
107- */
98+ /** Creates an instance with current time. */
10899 public static Timestamp now () {
109100 java .sql .Timestamp date = new java .sql .Timestamp (System .currentTimeMillis ());
110101 return of (date );
@@ -148,9 +139,7 @@ public int compareTo(Timestamp other) {
148139 return r ;
149140 }
150141
151- /**
152- * Creates an instance of Timestamp from {@code com.google.protobuf.Timestamp}.
153- */
142+ /** Creates an instance of Timestamp from {@code com.google.protobuf.Timestamp}. */
154143 public static Timestamp fromProto (com .google .protobuf .Timestamp proto ) {
155144 return new Timestamp (proto .getSeconds (), proto .getNanos ());
156145 }
@@ -168,28 +157,12 @@ public com.google.protobuf.Timestamp toProto() {
168157 * the timezone offset (always ends in "Z").
169158 */
170159 public static Timestamp parseTimestamp (String timestamp ) {
171- Matcher matcher = FORMAT_REGEXP .matcher (timestamp );
172- if (!matcher .matches ()) {
173- throw new IllegalArgumentException ("Cannot parse input: " + timestamp );
174- }
175- String secondsPart = matcher .group (1 );
176- String nanosPart = matcher .group (2 );
177- long seconds ;
178- seconds = format .parseMillis (secondsPart ) / 1000 ;
179- int nanos = 0 ;
180- if (nanosPart != null ) {
181- String padded = Strings .padEnd (nanosPart .substring (1 ), 9 , '0' );
182- nanos = Integer .parseInt (padded );
183- if (nanos >= TimeUnit .SECONDS .toNanos (1 )) {
184- throw new IllegalArgumentException (
185- "Cannot parse input: " + timestamp + " (nanos out of range)" );
186- }
187- }
188- return ofTimeSecondsAndNanos (seconds , nanos );
160+ Instant instant = Instant .parse (timestamp );
161+ return ofTimeSecondsAndNanos (instant .getEpochSecond (), instant .getNano ());
189162 }
190163
191- StringBuilder toString (StringBuilder b ) {
192- format .printTo ( b , seconds * 1000 );
164+ private StringBuilder toString (StringBuilder b ) {
165+ format .formatTo ( LocalDateTime . ofEpochSecond ( seconds , 0 , ZoneOffset . UTC ), b );
193166 if (nanos != 0 ) {
194167 b .append (String .format (".%09d" , nanos ));
195168 }
0 commit comments