151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.sql;
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.StringTokenizer;
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/**
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>A thin wrapper around <code>java.util.Date</code> that allows
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the JDBC API to identify this as an SQL <code>TIMESTAMP</code> value.
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * It adds the ability
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to hold the SQL <code>TIMESTAMP</code> fractional seconds value, by allowing
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the specification of fractional seconds to a precision of nanoseconds.
3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A Timestamp also provides formatting and
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * parsing operations to support the JDBC escape syntax for timestamp values.
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>The precision of a Timestamp object is calculated to be either:
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <ul>
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li><code>19 </code>, which is the number of characters in yyyy-mm-dd hh:mm:ss
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <li> <code> 20 + s </code>, which is the number
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of characters in the yyyy-mm-dd hh:mm:ss.[fff...] and <code>s</code> represents  the scale of the given Timestamp,
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * its fractional seconds precision.
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *</ul>
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P><B>Note:</B> This type is a composite of a <code>java.util.Date</code> and a
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * separate nanoseconds value. Only integral seconds are stored in the
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>java.util.Date</code> component. The fractional seconds - the nanos - are
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * separate.  The <code>Timestamp.equals(Object)</code> method never returns
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>true</code> when passed an object
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * that isn't an instance of <code>java.sql.Timestamp</code>,
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * because the nanos component of a date is unknown.
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * As a result, the <code>Timestamp.equals(Object)</code>
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method is not symmetric with respect to the
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>java.util.Date.equals(Object)</code>
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method.  Also, the <code>hashCode</code> method uses the underlying
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>java.util.Date</code>
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * implementation and therefore does not include nanos in its computation.
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Due to the differences between the <code>Timestamp</code> class
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and the <code>java.util.Date</code>
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * class mentioned above, it is recommended that code not view
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>Timestamp</code> values generically as an instance of
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>java.util.Date</code>.  The
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * inheritance relationship between <code>Timestamp</code>
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and <code>java.util.Date</code> really
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * denotes implementation inheritance, and not type inheritance.
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class Timestamp extends java.util.Date {
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Constructs a <code>Timestamp</code> object initialized
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with the given values.
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param year the year minus 1900
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param month 0 to 11
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param date 1 to 31
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param hour 0 to 23
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param minute 0 to 59
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param second 0 to 59
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param nano 0 to 999,999,999
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @deprecated instead use the constructor <code>Timestamp(long millis)</code>
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IllegalArgumentException if the nano argument is out of bounds
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @Deprecated
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Timestamp(int year, int month, int date,
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     int hour, int minute, int second, int nano) {
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        super(year, month, date, hour, minute, second);
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (nano > 999999999 || nano < 0) {
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("nanos > 999999999 or < 0");
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        nanos = nano;
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Constructs a <code>Timestamp</code> object
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * using a milliseconds time value. The
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * integral seconds are stored in the underlying date value; the
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * fractional seconds are stored in the <code>nanos</code> field of
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the <code>Timestamp</code> object.
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param time milliseconds since January 1, 1970, 00:00:00 GMT.
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *        A negative number is the number of milliseconds before
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         January 1, 1970, 00:00:00 GMT.
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see java.util.Calendar
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Timestamp(long time) {
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        super((time/1000)*1000);
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        nanos = (int)((time%1000) * 1000000);
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (nanos < 0) {
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nanos = 1000000000 + nanos;
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            super.setTime(((time/1000)-1)*1000);
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Sets this <code>Timestamp</code> object to represent a point in time that is
11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <tt>time</tt> milliseconds after January 1, 1970 00:00:00 GMT.
12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param time   the number of milliseconds.
12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getTime
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #Timestamp(long time)
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see java.util.Calendar
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setTime(long time) {
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        super.setTime((time/1000)*1000);
12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        nanos = (int)((time%1000) * 1000000);
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (nanos < 0) {
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nanos = 1000000000 + nanos;
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            super.setTime(((time/1000)-1)*1000);
13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * represented by this <code>Timestamp</code> object.
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return  the number of milliseconds since January 1, 1970, 00:00:00 GMT
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          represented by this date.
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #setTime
14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public long getTime() {
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long time = super.getTime();
14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return (time + (nanos / 1000000));
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @serial
15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private int nanos;
15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Converts a <code>String</code> object in JDBC timestamp escape format to a
15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>Timestamp</code> value.
15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param s timestamp in format <code>yyyy-[m]m-[d]d hh:mm:ss[.f...]</code>.  The
15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * fractional seconds may be omitted. The leading zero for <code>mm</code>
16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * and <code>dd</code> may also be omitted.
16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return corresponding <code>Timestamp</code> value
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception java.lang.IllegalArgumentException if the given argument
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * does not have the format <code>yyyy-[m]m-[d]d hh:mm:ss[.f...]</code>
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static Timestamp valueOf(String s) {
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        final int YEAR_LENGTH = 4;
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        final int MONTH_LENGTH = 2;
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        final int DAY_LENGTH = 2;
17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        final int MAX_MONTH = 12;
17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        final int MAX_DAY = 31;
17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String date_s;
17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String time_s;
17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String nanos_s;
17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int year = 0;
17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int month = 0;
17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int day = 0;
17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int hour;
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int minute;
18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int second;
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int a_nanos = 0;
18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int firstDash;
18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int secondDash;
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int dividingSpace;
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int firstColon = 0;
18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int secondColon = 0;
18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int period = 0;
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String formatError = "Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]";
18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String zeros = "000000000";
19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String delimiterDate = "-";
19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String delimiterTime = ":";
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (s == null) throw new java.lang.IllegalArgumentException("null string");
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Split the string into date and time components
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        s = s.trim();
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        dividingSpace = s.indexOf(' ');
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (dividingSpace > 0) {
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            date_s = s.substring(0,dividingSpace);
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            time_s = s.substring(dividingSpace+1);
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new java.lang.IllegalArgumentException(formatError);
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Parse the date
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        firstDash = date_s.indexOf('-');
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        secondDash = date_s.indexOf('-', firstDash+1);
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Parse the time
21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (time_s == null)
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new java.lang.IllegalArgumentException(formatError);
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        firstColon = time_s.indexOf(':');
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        secondColon = time_s.indexOf(':', firstColon+1);
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        period = time_s.indexOf('.', secondColon+1);
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Convert the date
21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        boolean parsedDate = false;
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ((firstDash > 0) && (secondDash > 0) && (secondDash < date_s.length() - 1)) {
21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            String yyyy = date_s.substring(0, firstDash);
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            String mm = date_s.substring(firstDash + 1, secondDash);
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            String dd = date_s.substring(secondDash + 1);
22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (yyyy.length() == YEAR_LENGTH &&
22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    (mm.length() >= 1 && mm.length() <= MONTH_LENGTH) &&
22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    (dd.length() >= 1 && dd.length() <= DAY_LENGTH)) {
22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 year = Integer.parseInt(yyyy);
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 month = Integer.parseInt(mm);
22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 day = Integer.parseInt(dd);
22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ((month >= 1 && month <= MAX_MONTH) && (day >= 1 && day <= MAX_DAY)) {
23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    parsedDate = true;
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (! parsedDate) {
23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new java.lang.IllegalArgumentException(formatError);
23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Convert the time; default missing nanos
23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ((firstColon > 0) & (secondColon > 0) &
24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            (secondColon < time_s.length()-1)) {
24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            hour = Integer.parseInt(time_s.substring(0, firstColon));
24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            minute =
24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Integer.parseInt(time_s.substring(firstColon+1, secondColon));
24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ((period > 0) & (period < time_s.length()-1)) {
24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                second =
24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    Integer.parseInt(time_s.substring(secondColon+1, period));
24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                nanos_s = time_s.substring(period+1);
24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (nanos_s.length() > 9)
24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    throw new java.lang.IllegalArgumentException(formatError);
25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (!Character.isDigit(nanos_s.charAt(0)))
25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    throw new java.lang.IllegalArgumentException(formatError);
25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                nanos_s = nanos_s + zeros.substring(0,9-nanos_s.length());
25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                a_nanos = Integer.parseInt(nanos_s);
25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else if (period > 0) {
25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new java.lang.IllegalArgumentException(formatError);
25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                second = Integer.parseInt(time_s.substring(secondColon+1));
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new java.lang.IllegalArgumentException(formatError);
26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return new Timestamp(year - 1900, month - 1, day, hour, minute, second, a_nanos);
26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Formats a timestamp in JDBC timestamp escape format.
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         <code>yyyy-mm-dd hh:mm:ss.fffffffff</code>,
26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * where <code>ffffffffff</code> indicates nanoseconds.
27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <P>
27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return a <code>String</code> object in
27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *           <code>yyyy-mm-dd hh:mm:ss.fffffffff</code> format
27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String toString () {
27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int year = super.getYear() + 1900;
27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int month = super.getMonth() + 1;
27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int day = super.getDate();
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int hour = super.getHours();
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int minute = super.getMinutes();
28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int second = super.getSeconds();
28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String yearString;
28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String monthString;
28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String dayString;
28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String hourString;
28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String minuteString;
28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String secondString;
28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String nanosString;
28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String zeros = "000000000";
29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String yearZeros = "0000";
29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        StringBuffer timestampBuf;
29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (year < 1000) {
29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Add leading zeros
29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            yearString = "" + year;
29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            yearString = yearZeros.substring(0, (4-yearString.length())) +
29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                yearString;
29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            yearString = "" + year;
30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (month < 10) {
30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            monthString = "0" + month;
30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            monthString = Integer.toString(month);
30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (day < 10) {
30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            dayString = "0" + day;
30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            dayString = Integer.toString(day);
31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (hour < 10) {
31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            hourString = "0" + hour;
31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            hourString = Integer.toString(hour);
31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (minute < 10) {
31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            minuteString = "0" + minute;
31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            minuteString = Integer.toString(minute);
32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (second < 10) {
32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            secondString = "0" + second;
32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            secondString = Integer.toString(second);
32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (nanos == 0) {
32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nanosString = "0";
32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nanosString = Integer.toString(nanos);
33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Add leading zeros
33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nanosString = zeros.substring(0, (9-nanosString.length())) +
33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                nanosString;
33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Truncate trailing zeros
33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            char[] nanosChar = new char[nanosString.length()];
33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nanosString.getChars(0, nanosString.length(), nanosChar, 0);
33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int truncIndex = 8;
33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while (nanosChar[truncIndex] == '0') {
34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                truncIndex--;
34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nanosString = new String(nanosChar, 0, truncIndex + 1);
34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // do a string buffer here instead.
34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        timestampBuf = new StringBuffer(20+nanosString.length());
34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        timestampBuf.append(yearString);
34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        timestampBuf.append("-");
35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        timestampBuf.append(monthString);
35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        timestampBuf.append("-");
35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        timestampBuf.append(dayString);
35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        timestampBuf.append(" ");
35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        timestampBuf.append(hourString);
35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        timestampBuf.append(":");
35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        timestampBuf.append(minuteString);
35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        timestampBuf.append(":");
35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        timestampBuf.append(secondString);
35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        timestampBuf.append(".");
36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        timestampBuf.append(nanosString);
36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return (timestampBuf.toString());
36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Gets this <code>Timestamp</code> object's <code>nanos</code> value.
36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return this <code>Timestamp</code> object's fractional seconds component
36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #setNanos
37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int getNanos() {
37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return nanos;
37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Sets this <code>Timestamp</code> object's <code>nanos</code> field
37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to the given value.
37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param n the new fractional seconds component
38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception java.lang.IllegalArgumentException if the given argument
38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *            is greater than 999999999 or less than 0
38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getNanos
38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setNanos(int n) {
38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (n > 999999999 || n < 0) {
38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("nanos > 999999999 or < 0");
38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        nanos = n;
38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Tests to see if this <code>Timestamp</code> object is
39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * equal to the given <code>Timestamp</code> object.
39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param ts the <code>Timestamp</code> value to compare with
39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return <code>true</code> if the given <code>Timestamp</code>
39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         object is equal to this <code>Timestamp</code> object;
39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         <code>false</code> otherwise
39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean equals(Timestamp ts) {
40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (super.equals(ts)) {
40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if  (nanos == ts.nanos) {
40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return true;
40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return false;
40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return false;
40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Tests to see if this <code>Timestamp</code> object is
41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * equal to the given object.
41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This version of the method <code>equals</code> has been added
41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to fix the incorrect
41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * signature of <code>Timestamp.equals(Timestamp)</code> and to preserve backward
41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * compatibility with existing class files.
42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Note: This method is not symmetric with respect to the
42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>equals(Object)</code> method in the base class.
42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param ts the <code>Object</code> value to compare with
42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return <code>true</code> if the given <code>Object</code> is an instance
42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         of a <code>Timestamp</code> that
42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         is equal to this <code>Timestamp</code> object;
42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         <code>false</code> otherwise
42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean equals(java.lang.Object ts) {
43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski      if (ts instanceof Timestamp) {
43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return this.equals((Timestamp)ts);
43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski      } else {
43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return false;
43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski      }
43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Indicates whether this <code>Timestamp</code> object is
44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * earlier than the given <code>Timestamp</code> object.
44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param ts the <code>Timestamp</code> value to compare with
44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return <code>true</code> if this <code>Timestamp</code> object is earlier;
44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *        <code>false</code> otherwise
44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean before(Timestamp ts) {
44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return compareTo(ts) < 0;
44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Indicates whether this <code>Timestamp</code> object is
45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * later than the given <code>Timestamp</code> object.
45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param ts the <code>Timestamp</code> value to compare with
45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return <code>true</code> if this <code>Timestamp</code> object is later;
45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *        <code>false</code> otherwise
45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean after(Timestamp ts) {
45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return compareTo(ts) > 0;
46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Compares this <code>Timestamp</code> object to the given
46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>Timestamp</code> object.
46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   ts   the <code>Timestamp</code> object to be compared to
46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                this <code>Timestamp</code> object
46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return  the value <code>0</code> if the two <code>Timestamp</code>
46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          objects are equal; a value less than <code>0</code> if this
47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          <code>Timestamp</code> object is before the given argument;
47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          and a value greater than <code>0</code> if this
47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          <code>Timestamp</code> object is after the given argument.
47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since   1.4
47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int compareTo(Timestamp ts) {
47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long thisTime = this.getTime();
47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long anotherTime = ts.getTime();
47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int i = (thisTime<anotherTime ? -1 :(thisTime==anotherTime?0 :1));
47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (i == 0) {
48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (nanos > ts.nanos) {
48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return 1;
48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else if (nanos < ts.nanos) {
48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return -1;
48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return i;
48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Compares this <code>Timestamp</code> object to the given
49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>Date</code> object.
49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param o the <code>Date</code> to be compared to
49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          this <code>Timestamp</code> object
49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return  the value <code>0</code> if this <code>Timestamp</code> object
49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          and the given object are equal; a value less than <code>0</code>
49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          if this  <code>Timestamp</code> object is before the given argument;
49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          and a value greater than <code>0</code> if this
50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          <code>Timestamp</code> object is after the given argument.
50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since   1.5
50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int compareTo(java.util.Date o) {
50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski       if(o instanceof Timestamp) {
50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // When Timestamp instance compare it with a Timestamp
50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Hence it is basically calling this.compareTo((Timestamp))o);
50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Note typecasting is safe because o is instance of Timestamp
50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski           return compareTo((Timestamp)o);
51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski      } else {
51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // When Date doing a o.compareTo(this)
51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // will give wrong results.
51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski          Timestamp ts = new Timestamp(o.getTime());
51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski          return this.compareTo(ts);
51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski      }
51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * {@inheritDoc}
52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The {@code hashCode} method uses the underlying {@code java.util.Date}
52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * implementation and therefore does not include nanos in its computation.
52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @Override
52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int hashCode() {
52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return super.hashCode();
52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final long serialVersionUID = 2745179027874758501L;
53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
533