datetime.java

来自「jtds的源码 是你学习java的好东西」· Java 代码 · 共 498 行 · 第 1/2 页

JAVA
498
字号
//jTDS JDBC Driver for Microsoft SQL Server and Sybase
//Copyright (C) 2004 The jTDS Project
//
//This library is free software; you can redistribute it and/or
//modify it under the terms of the GNU Lesser General Public
//License as published by the Free Software Foundation; either
//version 2.1 of the License, or (at your option) any later version.
//
//This library is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public
//License along with this library; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
package net.sourceforge.jtds.jdbc;

import java.sql.Date;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.GregorianCalendar;

/**
 * Encapsulates Sybase date/time values and provides conversions to and from
 * Java classes.
 *
 * @author Mike Hutchinson
 * @version $Id: DateTime.java,v 1.4 2005/07/11 13:33:30 alin_sinpalean Exp $
 */
public class DateTime {
    /** Per thread instance of Calendar used for conversions. */
    private static ThreadLocal calendar = new ThreadLocal() {
        protected synchronized Object initialValue() {
            return new GregorianCalendar();
        }
    };
    /** Indicates date value not used. */
    static final int DATE_NOT_USED = Integer.MIN_VALUE;
    /** Indicates time value not used. */
    static final int TIME_NOT_USED = Integer.MIN_VALUE;
    /** The date component of the server datetime value. */
    private int   date;
    /** The time component of the server datetime value. */
    private int   time;
    /** Unpacked year value. */
    private short year;
    /** Unpacked month value. */
    private short month;
    /** Unpacked day value. */
    private short day;
    /** Unpacked hour value. */
    private short hour;
    /** Unpacked minute value. */
    private short minute;
    /** Unpacked second value. */
    private short second;
    /** Unpacked millisecond value. */
    private short millis;
    /** Indicates server datetime values have been unpacked. */
    private boolean unpacked;
    /** Cached value of the datetime as a <code>String</code>. */
    private String    stringValue;
    /** Cached value of the datetime as a <code>java.sql.Timestamp</code>. */
    private Timestamp tsValue;
    /** Cached value of the datetime as a <code>java.sql.Date</code>. */
    private Date      dateValue;
    /** Cached value of the datetime as a <code>java.sql.Time</code>. */
    private Time      timeValue;

    /**
     * Constructs a DateTime object from the two integer components of a
     * datetime.
     *
     * @param date server date field
     * @param time server time field
     */
    DateTime(int date, int time) {
        this.date = date;
        this.time = time;
    }

    /**
     * Constructs a DateTime object from the two short components of a
     * smalldatetime.
     *
     * @param date server date field
     * @param time server time field
     */
    DateTime(short date, short time) {
        this.date = (int) date & 0xFFFF;
        this.time = (int) time * 60 * 300;
    }

    /**
     * Constructs a DateTime object from a <code>java.sql.Timestamp</code>.
     *
     * @param ts <code>Timestamp</code> object representing the datetime
     * @throws SQLException if the date is out of range
     */
    DateTime(Timestamp ts) throws SQLException {
        tsValue = ts;
        GregorianCalendar cal = (GregorianCalendar)calendar.get();
        cal.setTime((java.util.Date) ts);

        if (!Driver.JDBC3) {
            // Not Running under 1.4 so need to add milliseconds
            cal.set(Calendar.MILLISECOND,
                    ((Timestamp)ts).getNanos() / 1000000);
        }
        this.year   = (short)cal.get(Calendar.YEAR);
        this.month  = (short)(cal.get(Calendar.MONTH) + 1);
        this.day    = (short)cal.get(Calendar.DAY_OF_MONTH);
        this.hour   = (short)cal.get(Calendar.HOUR_OF_DAY);
        this.minute = (short)cal.get(Calendar.MINUTE);
        this.second = (short)cal.get(Calendar.SECOND);
        this.millis = (short)cal.get(Calendar.MILLISECOND);
        packDate();
        packTime();
        unpacked = true;
    }

    /**
     * Constructs a DateTime object from a <code>java.sql.Time</code>.
     *
     * @param t <code>Time</code> object representing the datetime
     */
    DateTime(Time t) {
        timeValue = t;
        GregorianCalendar cal = (GregorianCalendar)calendar.get();
        cal.setTime((java.util.Date) t);
        this.date   = DATE_NOT_USED;
        this.year   = 1900;
        this.month  = 1;
        this.day    = 1;
        this.hour   = (short)cal.get(Calendar.HOUR_OF_DAY);
        this.minute = (short)cal.get(Calendar.MINUTE);
        this.second = (short)cal.get(Calendar.SECOND);
        this.millis = (short)cal.get(Calendar.MILLISECOND);
        packTime();
        this.year  = 1970;
        this.month = 1;
        this.day   = 1;
        unpacked   = true;
    }

    /**
     * Constructs a DateTime object from a <code>java.sql.Date</code>.
     *
     * @param d <code>Date</code> object representing the datetime
     * @throws SQLException if the Date is out of range
     */
    DateTime(Date d) throws SQLException {
        dateValue = d;
        GregorianCalendar cal = (GregorianCalendar)calendar.get();
        cal.setTime((java.util.Date) d);
        this.year   = (short)cal.get(Calendar.YEAR);
        this.month  = (short)(cal.get(Calendar.MONTH) + 1);
        this.day    = (short)cal.get(Calendar.DAY_OF_MONTH);
        this.hour   = 0;
        this.minute = 0;
        this.second = 0;
        this.millis = 0;
        packDate();
        this.time = TIME_NOT_USED;
        unpacked  = true;
    }

    /**
     * Retrieves the date component of a datetime value.
     *
     * @return the datetime date component as an <code>int</code>
     */
    int getDate() {
        return (date == DATE_NOT_USED) ? 0 : date;
    }

    /**
     * Retrieves the time component of a datetime value.
     *
     * @return the datetime time component as an <code>int</code>
     */
    int getTime() {
        return (time == TIME_NOT_USED) ? 0 : time;
    }

    /**
     * Converts a Julian datetime from the Sybase epoch of 1900-01-01 to the
     * equivalent unpacked year/month/day etc.
     *
     * Algorithm  from Fliegel, H F and van Flandern, T C (1968).
     * Communications of the ACM, Vol 11, No 10 (October, 1968).
     * <pre>
     *           SUBROUTINE GDATE (JD, YEAR,MONTH,DAY)
     *     C
     *     C---COMPUTES THE GREGORIAN CALENDAR DATE (YEAR,MONTH,DAY)
     *     C   GIVEN THE JULIAN DATE (JD).
     *     C
     *           INTEGER JD,YEAR,MONTH,DAY,I,J,K
     *     C
     *           L= JD+68569
     *           N= 4*L/146097
     *           L= L-(146097*N+3)/4
     *           I= 4000*(L+1)/1461001
     *           L= L-1461*I/4+31
     *           J= 80*L/2447
     *           K= L-2447*J/80
     *           L= J/11
     *           J= J+2-12*L
     *           I= 100*(N-49)+I+L
     *     C
     *           YEAR= I
     *           MONTH= J
     *           DAY= K
     *     C
     *           RETURN
     *           END
     * </pre>
     */
    private void unpackDateTime() {
        if (this.date == DATE_NOT_USED) {
            this.year  = 1970;
            this.month = 1;
            this.day   = 1;
        } else {
            if (date == 0) {
                // Optimize common case of 1900-01-01 which is used as
                // the default date for datetimes where only the time is set.
                this.year  = 1900;
                this.month = 1;
                this.day   = 1;
            } else {
                int l = date + 68569 + 2415021;
                int n = 4 * l / 146097;
                l = l - (146097 * n + 3) / 4;
                int i = 4000 * (l + 1) / 1461001;
                l = l - 1461 * i / 4 + 31;
                int j = 80 * l / 2447;
                int k = l - 2447 * j / 80;
                l = j / 11;
                j = j + 2 - 12 * l;
                i = 100 * (n - 49) + i + l;
                this.year  = (short)i;
                this.month = (short)j;
                this.day   = (short)k;
            }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?