1f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.sql; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.text.ParsePosition; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.text.SimpleDateFormat; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Date; 23f58ca9d9ff8540a146a0031d5557881f8b66f348Johan Redestigimport java.util.Locale; 24142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilsonimport java.util.regex.Pattern; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A Java representation of the SQL {@code TIMESTAMP} type. It provides the 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * capability of representing the SQL {@code TIMESTAMP} nanosecond value, in 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * addition to the regular date/time value which has millisecond resolution. 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The {@code Timestamp} class consists of a regular date/time value, where only 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the integral seconds value is stored, plus a nanoseconds value where the 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * fractional seconds are stored. 34142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson * <p> 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The addition of the nanosecond value field to the {@code Timestamp} object 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * makes it significantly different from the {@code java.util.Date} object which 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * it extends. Users should be aware that {@code Timestamp} objects are not 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * interchangable with {@code java.util.Date} objects when used outside the 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * confines of the {@code java.sql} package. 40142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson * 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Date 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Time 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.util.Date 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class Timestamp extends Date { 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 2745179027874758501L; 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The nanoseconds time value of the Timestamp 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int nanos; 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 52143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes // The regex pattern of yyyy-MM-dd HH:mm:ss 5303c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes private static final String TIME_FORMAT_REGEX = "[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}.*"; 54142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a {@code Timestamp} corresponding to the time specified by the 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * supplied values for <i>Year</i>, <i>Month</i>, <i>Date</i>, <i>Hour</i>, 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <i>Minutes</i>, <i>Seconds</i> and <i>Nanoseconds</i>. 59142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson * 6099b4489d0555c6e0e5df941cbfad4cf250c8f0b8Elliott Hughes * @deprecated Use the constructor {@link #Timestamp(long)} instead. 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param theYear 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified as the year minus 1900. 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param theMonth 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified as an integer in the range [0,11]. 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param theDate 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified as an integer in the range [1,31]. 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param theHour 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified as an integer in the range [0,23]. 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param theMinute 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified as an integer in the range [0,59]. 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param theSecond 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified as an integer in the range [0,59]. 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param theNano 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * which defines the nanosecond value of the timestamp specified 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * as an integer in the range [0,999'999'999] 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if any of the parameters is out of range. 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @SuppressWarnings("deprecation") 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Deprecated 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Timestamp(int theYear, int theMonth, int theDate, int theHour, 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int theMinute, int theSecond, int theNano) 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IllegalArgumentException { 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(theYear, theMonth, theDate, theHour, theMinute, theSecond); 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (theNano < 0 || theNano > 999999999) { 86cff1616012dc0d56c2da9af2b9b1183e76c7e044Elliott Hughes throw new IllegalArgumentException("ns out of range: " + theNano); 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nanos = theNano; 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a {@code Timestamp} object corresponding to the time represented 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * by a supplied time value. 94f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param theTime 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a time value in the format of milliseconds since the Epoch 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (January 1 1970 00:00:00.000 GMT). 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Timestamp(long theTime) { 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(theTime); 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Now set the time for this Timestamp object - which deals with the 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * nanosecond value as well as the base time 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 105142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson setTimeImpl(theTime); 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns {@code true} if this timestamp object is later than the supplied 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * timestamp, otherwise returns {@code false}. 111f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param theTimestamp 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the timestamp to compare with this timestamp object. 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this {@code Timestamp} object is later than the 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * supplied timestamp, {@code false} otherwise. 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean after(Timestamp theTimestamp) { 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long thisTime = this.getTime(); 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long compareTime = theTimestamp.getTime(); 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If the time value is later, the timestamp is later 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (thisTime > compareTime) { 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If the time value is earlier, the timestamp is not later 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project else if (thisTime < compareTime) { 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Otherwise the time values are equal in which case the nanoseconds 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * value determines whether this timestamp is later... 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project else if (this.getNanos() > theTimestamp.getNanos()) { 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns {@code true} if this {@code Timestamp} object is earlier than the 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * supplied timestamp, otherwise returns {@code false}. 143f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param theTimestamp 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the timestamp to compare with this {@code Timestamp} object. 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this {@code Timestamp} object is earlier than the 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * supplied timestamp, {@code false} otherwise. 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean before(Timestamp theTimestamp) { 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long thisTime = this.getTime(); 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long compareTime = theTimestamp.getTime(); 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If the time value is later, the timestamp is later 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (thisTime < compareTime) { 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If the time value is earlier, the timestamp is not later 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project else if (thisTime > compareTime) { 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Otherwise the time values are equal in which case the nanoseconds 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * value determines whether this timestamp is later... 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project else if (this.getNanos() < theTimestamp.getNanos()) { 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Compares this {@code Timestamp} object with a supplied {@code Timestamp} 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * object. 175f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param theObject 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the timestamp to compare with this {@code Timestamp} object, 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * passed as an {@code Object}. 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return <dd> 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <dl> 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code 0} if the two {@code Timestamp} objects are equal in time 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </dl> 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <dl> 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a value {@code < 0} if this {@code Timestamp} object is before 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the supplied {@code Timestamp} and a value 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </dl> 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <dl> 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code > 0} if this {@code Timestamp} object is after the 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * supplied {@code Timestamp} 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </dl> 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </dd> 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassCastException 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the supplied object is not a {@code Timestamp} object. 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int compareTo(Date theObject) throws ClassCastException { 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this.compareTo((Timestamp) theObject); 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Compares this {@code Timestamp} object with a supplied {@code Timestamp} 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * object. 203f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param theTimestamp 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the timestamp to compare with this {@code Timestamp} object, 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * passed in as a {@code Timestamp}. 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return one of the following: 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ul> 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>{@code 0}, if the two {@code Timestamp} objects are 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * equal in time</li> 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>{@code < 0}, if this {@code Timestamp} object is before the 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * supplied {@code Timestamp}</li> 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li> {@code > 0}, if this {@code Timestamp} object is after the 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * supplied {@code Timestamp}</li> 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ul> 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int compareTo(Timestamp theTimestamp) { 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int result = super.compareTo(theTimestamp); 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == 0) { 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int thisNano = this.getNanos(); 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int thatNano = theTimestamp.getNanos(); 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (thisNano > thatNano) { 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 1; 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (thisNano == thatNano) { 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return -1; 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Tests to see if this timestamp is equal to a supplied object. 235f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param theObject 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the object to which this timestamp is compared. 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this {@code Timestamp} object is equal to the 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * supplied {@code Timestamp} object<br>{@code false} if the object 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is not a {@code Timestamp} object or if the object is a {@code 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Timestamp} but represents a different instant in time. 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean equals(Object theObject) { 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (theObject instanceof Timestamp) { 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return equals((Timestamp) theObject); 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Tests to see if this timestamp is equal to a supplied timestamp. 253f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param theTimestamp 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the timestamp to compare with this {@code Timestamp} object, 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * passed as an {@code Object}. 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this {@code Timestamp} object is equal to the 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * supplied {@code Timestamp} object, {@code false} otherwise. 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean equals(Timestamp theTimestamp) { 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (theTimestamp == null) { 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (this.getTime() == theTimestamp.getTime()) 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && (this.getNanos() == theTimestamp.getNanos()); 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets this {@code Timestamp}'s nanosecond value 270f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return The timestamp's nanosecond value, an integer between 0 and 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 999,999,999. 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getNanos() { 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return nanos; 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the time represented by this {@code Timestamp} object, as a long 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * value containing the number of milliseconds since the Epoch (January 1 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 1970, 00:00:00.000 GMT). 282142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson * 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of milliseconds that have passed since January 1 1970, 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 00:00:00.000 GMT. 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long getTime() { 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long theTime = super.getTime(); 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project theTime = theTime + (nanos / 1000000); 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return theTime; 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets the nanosecond value for this {@code Timestamp}. 295142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson * 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param n 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * number of nanoseconds. 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if number of nanoseconds smaller than 0 or greater than 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 999,999,999. 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setNanos(int n) throws IllegalArgumentException { 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((n < 0) || (n > 999999999)) { 30403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("Value out of range"); 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nanos = n; 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets the time represented by this {@code Timestamp} object to the 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * supplied time, defined as the number of milliseconds since the Epoch 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (January 1 1970, 00:00:00.000 GMT). 313142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson * 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param theTime 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * number of milliseconds since the Epoch (January 1 1970, 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 00:00:00.000 GMT). 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setTime(long theTime) { 320142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson setTimeImpl(theTime); 321142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson } 322f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 323142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson private void setTimeImpl(long theTime) { 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Deal with the nanoseconds value. The supplied time is in milliseconds - 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * so we must extract the milliseconds value and multiply by 1000000 to 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * get nanoseconds. Things are more complex if theTime value is 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * negative, since then the time value is the time before the Epoch but 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the nanoseconds value of the Timestamp must be positive - so we must 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * take the "raw" milliseconds value and subtract it from 1000 to get to 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the true nanoseconds value Simultaneously, recalculate the time value 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to the exact nearest second and reset the Date time value 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int milliseconds = (int) (theTime % 1000); 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project theTime = theTime - milliseconds; 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (milliseconds < 0) { 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project theTime = theTime - 1000; 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project milliseconds = 1000 + milliseconds; 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super.setTime(theTime); 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project setNanos(milliseconds * 1000000); 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the timestamp formatted as a String in the JDBC Timestamp Escape 346143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes * format, which is {@code "yyyy-MM-dd HH:mm:ss.nnnnnnnnn"}. 347f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return A string representing the instant defined by the {@code 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Timestamp}, in JDBC Timestamp escape format. 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @SuppressWarnings("deprecation") 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 354142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson StringBuilder sb = new StringBuilder(29); 355142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson 356142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson format((getYear() + 1900), 4, sb); 357142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson sb.append('-'); 358142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson format((getMonth() + 1), 2, sb); 359142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson sb.append('-'); 360142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson format(getDate(), 2, sb); 361142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson sb.append(' '); 362142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson format(getHours(), 2, sb); 363142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson sb.append(':'); 364142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson format(getMinutes(), 2, sb); 365142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson sb.append(':'); 366142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson format(getSeconds(), 2, sb); 367142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson sb.append('.'); 368142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson if (nanos == 0) { 369142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson sb.append('0'); 370142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson } else { 371142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson format(nanos, 9, sb); 372142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson while (sb.charAt(sb.length() - 1) == '0') { 373142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson sb.setLength(sb.length() - 1); 374142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson } 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 376142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson 377142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson return sb.toString(); 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 38003c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes private static final String PADDING = "000000000"; 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 382f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes /* 383f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * Private method to format the time 384f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes */ 385f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes private void format(int date, int digits, StringBuilder sb) { 386142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson String str = String.valueOf(date); 387142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson if (digits - str.length() > 0) { 388142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson sb.append(PADDING.substring(0, digits - str.length())); 389142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson } 390f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes sb.append(str); 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a {@code Timestamp} object with a time value equal to the time 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified by a supplied String holding the time in JDBC timestamp escape 396143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes * format, which is {@code "yyyy-MM-dd HH:mm:ss.nnnnnnnnn}" 397f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param s 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code String} containing a time in JDBC timestamp escape 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * format. 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return A {@code Timestamp} object with time value as defined by the 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * supplied {@code String}. 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the provided string is {@code null}. 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static Timestamp valueOf(String s) throws IllegalArgumentException { 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (s == null) { 40803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("Argument cannot be null"); 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 41103c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes // omit trailing whitespace 412142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson s = s.trim(); 413142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson if (!Pattern.matches(TIME_FORMAT_REGEX, s)) { 41403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw badTimestampString(s); 415142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson } 416142d526f8bf90fb9bb63c637beb5299f39791f55Jesse Wilson 417f58ca9d9ff8540a146a0031d5557881f8b66f348Johan Redestig SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US); 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ParsePosition pp = new ParsePosition(0); 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * First parse out the yyyy-MM-dd HH:mm:ss component of the String into 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a Date object using the SimpleDateFormat. This should stop after the 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * seconds value, according to the definition of SimpleDateFormat.parse, 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with the ParsePosition indicating the index of the "." which should 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * precede the nanoseconds value 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Date theDate; 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project theDate = df.parse(s, pp); 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (Exception e) { 43103c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw badTimestampString(s); 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (theDate == null) { 43503c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw badTimestampString(s); 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If we get here, the Date part of the string was OK - now for the 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * nanoseconds value. Strictly, this requires the remaining part of the 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * String to look like ".nnnnnnnnn". However, we accept anything with a 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * '.' followed by 1 to 9 digits - we also accept nothing (no fractions 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of a second). Anything else is interpreted as incorrect format which 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * will generate an IllegalArgumentException 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int position = pp.getIndex(); 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int remaining = s.length() - position; 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int theNanos; 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (remaining == 0) { 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // First, allow for the case where no fraction of a second is given: 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project theNanos = 0; 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Case where fraction of a second is specified: Require 1 character 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * plus the "." in the remaining part of the string... 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 45803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if ((s.length() - position) < ".n".length()) { 45903c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw badTimestampString(s); 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If we're strict, we should not allow any EXTRA characters after 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the 9 digits 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 46603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if ((s.length() - position) > ".nnnnnnnnn".length()) { 46703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw badTimestampString(s); 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Require the next character to be a "." 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (s.charAt(position) != '.') { 47203c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new NumberFormatException("Bad input string format: expected '.' not '" + 4731f07ea29bc2d334c55c16227582a7795b8c117c1Elliott Hughes s.charAt(position) + "' in \"" + s + "\""); 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Get the length of the number string - need to account for the '.' 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int nanoLength = s.length() - position - 1; 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Get the 9 characters following the "." as an integer 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String theNanoString = s.substring(position + 1, position + 1 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project + nanoLength); 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * We must adjust for the cases where the nanos String was not 9 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * characters long by padding out with zeros 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 48503c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes theNanoString = theNanoString + "000000000"; 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project theNanoString = theNanoString.substring(0, 9); 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project theNanos = Integer.parseInt(theNanoString); 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (Exception e) { 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If we get here, the string was not a number 49203c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw badTimestampString(s); 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (theNanos < 0 || theNanos > 999999999) { 49703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw badTimestampString(s); 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Timestamp theTimestamp = new Timestamp(theDate.getTime()); 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project theTimestamp.setNanos(theNanos); 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return theTimestamp; 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 505f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 50603c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes private static IllegalArgumentException badTimestampString(String s) { 50703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("Timestamp format must be " + 508143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes "yyyy-MM-dd HH:mm:ss.fffffffff; was '" + s + "'"); 50903c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes } 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 511