blob: 8e2c62a511fb919f4c61fbaeb43bf8bbab09f1bb [file] [log] [blame]
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package java.sql;
/**
* An implementation of java.sql.Timestame. Derived from
* http://java.sun.com/j2se/1.5.0/docs/api/java/sql/Timestamp.html. This is
* basically just regular Date decorated with a nanoseconds field.
*/
public class Timestamp extends java.util.Date {
public static Timestamp valueOf(String s) {
String[] components = s.split(" ");
if (components.length != 2) {
throw new IllegalArgumentException("Invalid escape format: " + s);
}
String[] timeComponents = components[1].split("\\.");
boolean hasNanos = true;
int nanos = 0;
if (timeComponents.length == 1) {
// Allow timestamps without .fffffffff nanoseconds field
hasNanos = false;
} else if (timeComponents.length != 2) {
throw new IllegalArgumentException("Invalid escape format: " + s);
}
Date d = Date.valueOf(components[0]);
Time t = Time.valueOf(timeComponents[0]);
if (hasNanos) {
String nanosString = timeComponents[1];
int len = nanosString.length();
assert len > 0; // len must be > 0 if hasNanos is true
if (len > 9) {
throw new IllegalArgumentException("Invalid escape format: " + s);
}
// Pad zeros on the right up to a total of 9 digits
if (len < 9) {
nanosString += "00000000".substring(len - 1);
}
try {
nanos = Integer.valueOf(nanosString);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid escape format: " + s);
}
}
return new Timestamp(d.getYear(), d.getMonth(), d.getDate(), t.getHours(),
t.getMinutes(), t.getSeconds(), nanos);
}
private static String padNine(int value) {
StringBuffer toReturn = new StringBuffer("000000000");
assert toReturn.length() == 9;
String asString = String.valueOf(value);
toReturn = toReturn.replace(9 - asString.length(), 9, asString);
assert toReturn.length() == 9;
return toReturn.toString();
}
/**
* Stores the nanosecond resolution of the timestamp; must be kept in sync
* with the sub-second part of Date.millis.
*/
private int nanos;
@Deprecated
public Timestamp(int year, int month, int date, int hour, int minute,
int second, int nano) {
super(year, month, date, hour, minute, second);
setNanos(nano);
}
public Timestamp(long time) {
super(time);
// Seed the milliseconds in nanos
nanos = (((int) (time % 1000)) * 1000000);
}
public boolean after(Timestamp ts) {
return (getTime() > ts.getTime())
|| (getTime() == ts.getTime() && getNanos() > ts.getNanos());
}
public boolean before(Timestamp ts) {
return (getTime() < ts.getTime())
|| (getTime() == ts.getTime() && getNanos() < ts.getNanos());
}
@Override
public int compareTo(java.util.Date o) {
if (o instanceof Timestamp) {
return compareTo((Timestamp) o);
} else {
return compareTo(new Timestamp(o.getTime()));
}
}
public int compareTo(Timestamp o) {
int delta = (int) (getTime() - o.getTime());
return delta == 0 ? getNanos() - o.getNanos() : delta;
}
@Override
public boolean equals(Object ts) {
// Timestamps can't be compared to java.util.Date
// This is known to not be symmetric, which follows the JRE.
return ts instanceof Timestamp ? equals((Timestamp) ts) : false;
}
public boolean equals(Timestamp ts) {
return (getTime() == ts.getTime() && getNanos() == ts.getNanos());
}
public int getNanos() {
return nanos;
}
@Override
public long getTime() {
return super.getTime();
}
@Override
public int hashCode() {
// This is correct, per the Javadoc
return super.hashCode();
}
public void setNanos(int n) {
if (n < 0 || n > 999999999) {
throw new IllegalArgumentException("nanos out of range " + n);
}
nanos = n;
// Clear the sub-second part of the date; replace with new nanos.
super.setTime((getTime() / 1000) * 1000 + (nanos / 1000000));
}
@Override
public void setTime(long time) {
super.setTime(time);
nanos = (((int) (time % 1000)) * 1000000);
}
@Override
public String toString() {
return String.valueOf(1900 + getYear()) + "-" + padTwo(1 + getMonth())
+ "-" + padTwo(getDate()) + " " + padTwo(getHours()) + ":"
+ padTwo(getMinutes()) + ":" + padTwo(getSeconds()) + "."
+ padNine(getNanos());
}
}