Date类源码阅读

Java中的Date类最初包含日期时间解析、格式化功能,但在JDK1.1后,这些功能被Calendar和DateFormat替代。Date类现主要用于表示时间的毫秒值,与Calendar类配合处理日期时间计算。废弃的方法不再被推荐使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    从类说明中截取了一小段进行了翻译解说明Date类,我觉得对Date有一个初步对象(JDK1.7):
    Date类代表一个毫秒值精度的时间。在JDK1.1之前,Date类有两个额外的功能。第一个是允许将时间解释为年、月、日、小时、分钟、秒。另一个就是能格式化和装换时间字符串。不幸的是,在国际化的过程这些功表现并不好。所以在1.1版本中,Calendar类被用来在时间、时间属性与DateFormat类(用作格式和时间字符串转换)之间的转换Date类中的相应方法都被遗弃了。
    从类说明中我们也看到了Date类中有很多的方法都被遗弃了,所以对于遗弃的方法这里也不会太关注了,主要关注在目前还能使用的方法,遗弃的方法都会被建议使用Calendar、GregorianCalendar类、DateFormat类的相应方法。Date基本保留成为一个表征时间的功能,对于时间的计算基本都是有Calendar类或相关的类完成。Date中最关键的就是这个毫秒值,很多的方法都是来自于这个。


```

/**
 * Date类代表一个毫秒值精度的时间
 * <p>
 * 在JDK1.1之前,Date类有两个额外的功能。第一个是允许将时间解释为年、月、日、小时、分钟、秒。
 * 另一个就是能格式化和装换时间字符串。不幸的是,在国际化的过程这些功表现并不好。
 * 所以在1.1版本中,Calendar类被用来在时间、时间属性与DateFormat类(用作格式和时间支付串转换)之间的转换
 * Date类中的相应方法都被遗弃了。
 *介绍了闰秒和其它想关知识,并不关心
 *
 * @author  James Gosling
 * @author  Arthur van Hoff
 * @author  Alan Liu
 * @see     java.text.DateFormat
 * @see     java.util.Calendar
 * @see     java.util.TimeZone
 * @since   JDK1.0
 */
public class Date
    implements java.io.Serializable, Cloneable, Comparable<Date>
{
    private static final BaseCalendar gcal =
                                CalendarSystem.getGregorianCalendar();
    private static BaseCalendar jcal;

    private transient long fastTime;

    /*
     * If cdate is null, then fastTime indicates the time in millis.
     * If cdate.isNormalized() is true, then fastTime and cdate are in
     * synch. Otherwise, fastTime is ignored, and cdate indicates the
     * time.
     */
    private transient BaseCalendar.Date cdate;

    // Initialized just before the value is used. See parse().
    private static int defaultCenturyStart;


    private static final long serialVersionUID = 7523967970034938905L;

    /**
     * 初始化一个Date对象并初始化,用系统毫秒值来初始化
     *
     * @see java.lang.System#currentTimeMillis()
     */
    public Date() {
        this(System.currentTimeMillis());
    }

    /**
     * 用一个基础时间(1970-01-01,00:00:00格林威治时间)到现在的毫秒值初始化Date对象
     *
     * @param   date  从1970-01-01 00:00:00开始的一个毫秒值
     * @see     java.lang.System#currentTimeMillis()
     */
    public Date(long date) {
        fastTime = date;
    }

    /**
     * 废弃方法:建议使用Calendar.set(year+1900,month,date)或者GregorianCalendar(year+1900,month,date)
     * 分配并初始化一个Date对象,用来代表一个参数设置的开始时间
     *
     * @param   year    年份-1900.
     * @param   month   0-11取值月份.
     * @param   date    1-31取值天数.
     * @see     java.util.Calendar
     * @deprecated As of JDK version 1.1,
     *
     */
    @Deprecated
    public Date(int year, int month, int date) {
        this(year, month, date, 0, 0, 0);
    }

    /**
     * 废弃方法:建议使用Calendar类或者GregorianCalendar类的相关方法初始化时间
     *
     * @param   year    时间-1900.
     * @param   month   月份取值0-11.
     * @param   date    天数取值1-31.
     * @param   hrs     小时取值0-23.
     * @param   min     分钟取值0-59.
     * @see     java.util.Calendar
     * @deprecated As of JDK version 1.1,
     */
    @Deprecated
    public Date(int year, int month, int date, int hrs, int min) {
        this(year, month, date, hrs, min, 0);
    }

    /**
     * 废弃方法:建议使用Calendar类或者GregorianCalendar类的相关方法初始化时间
     *
     * @param   year    the year minus 1900.
     * @param   month   the month between 0-11.
     * @param   date    the day of the month between 1-31.
     * @param   hrs     the hours between 0-23.
     * @param   min     the minutes between 0-59.
     * @param   sec     the seconds between 0-59.
     * @see     java.util.Calendar
     * @deprecated As of JDK version 1.1,
     */
    @Deprecated
    //TODO
    public Date(int year, int month, int date, int hrs, int min, int sec) {
        int y = year + 1900;
        // month is 0-based. So we have to normalize month to support Long.MAX_VALUE.
        if (month >= 12) {//月份值比12大就变成年份值增加,然后月份取余
            y += month / 12;
            month %= 12;
        } else if (month < 0) {
            y += CalendarUtils.floorDivide(month, 12);
            month = CalendarUtils.mod(month, 12);
        }
        BaseCalendar cal = getCalendarSystem(y);
        cdate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef());
        cdate.setNormalizedDate(y, month + 1, date).setTimeOfDay(hrs, min, sec, 0);
        getTimeImpl();
        cdate = null;
    }

    /**
     * 废弃方法:建议使用DateFormat.parse(String s)
     *
     * @param   s   时间的字符串.
     * @see     java.text.DateFormat
     * @see     java.util.Date#parse(java.lang.String)
     * @deprecated As of JDK version 1.1,
      */
    @Deprecated
    public Date(String s) {
        this(parse(s));
    }

    /**
     *复制对象
     */
    public Object clone() {
        Date d = null;
        try {
            d = (Date)super.clone();
            if (cdate != null) {
                d.cdate = (BaseCalendar.Date) cdate.clone();
            }
        } catch (CloneNotSupportedException e) {} // Won't happen
        return d;
    }


    /**
     * 返回January 1, 1970, 00:00:00 GMT开始的毫秒值,代表时间对象
     *
     * @return  从January 1, 1970, 00:00:00 GMT向后的毫秒值代表这个时间
     */
    public long getTime() {
        return getTimeImpl();
    }

    private final long getTimeImpl() {
        if (cdate != null && !cdate.isNormalized()) {
            normalize();
        }
        return fastTime;
    }

    /**
     * 用从January 1, 1970 00:00:00 GMT的毫秒值设置Date对象表征这个时间点
     *
     * @param   time   毫秒值
     */
    public void setTime(long time) {
        fastTime = time;
        cdate = null;
    }

    /**
     * 测试时间是否在传入的时间的前面
     * 采用对应的毫秒值进行比较大小,用<
     *
     * @param   when   a date.
     * @return  严格的早于传入的时间
     * @exception NullPointerException if <code>when</code> is null.
     */
    public boolean before(Date when) {
        return getMillisOf(this) < getMillisOf(when);
    }

    /**
     * 测试调用方法的时间对象在传入时间对象后面
     *
     * @param   when   a date.
     * @return  严格的晚于传入时间
     * @exception NullPointerException if <code>when</code> is null.
     */
    public boolean after(Date when) {
        return getMillisOf(this) > getMillisOf(when);
    }

    /**
     * 比较两个时间是否相等
     * 当传入的参数不为null而且是一个代表同一个时间点的Date对象(毫秒值一样)返回true
     * @param   obj   the object to compare with.
     * @return  <code>true</code> if the objects are the same;
     *          <code>false</code> otherwise.
     * @see     java.util.Date#getTime()
     */
    public boolean equals(Object obj) {//做了类型检查
        return obj instanceof Date && getTime() == ((Date) obj).getTime();
    }

    /**
     *返回没有内部状态影响时间对象的毫秒值
     */
    static final long getMillisOf(Date date) {
        if (date.cdate == null || date.cdate.isNormalized()) {
            return date.fastTime;
        }
        BaseCalendar.Date d = (BaseCalendar.Date) date.cdate.clone();
        return gcal.getTime(d);
    }

    /**
     * 对两个时间对象进行排序比较
     *
     * @param   anotherDate   the <code>Date</code> to be compared.
     * @return  如果当前Date对象和传入的Date对象相等,返回0
     *          如果当前的Date对象早于传入的Date对象,返回<0
     *          如果当前的Date对象晚于传入的Date对象,返回>0
     * @since   1.2
     * @exception NullPointerException if <code>anotherDate</code> is null.
     */
    public int compareTo(Date anotherDate) {
        long thisTime = getMillisOf(this);
        long anotherTime = getMillisOf(anotherDate);
        return (thisTime<anotherTime ? -1 : (thisTime==anotherTime ? 0 : 1));
    }

    /**
     *返回对象的Hash值,这里是用时间的毫秒值异或毫秒值除以2^32,也就是右移32位
     *也可以理解为就是毫秒值
     *
     * @return  a hash code value for this object.
     */
    public int hashCode() {
        long ht = this.getTime();
        return (int) ht ^ (int) (ht >> 32);
    }

    private final BaseCalendar.Date getCalendarDate() {
        if (cdate == null) {
            BaseCalendar cal = getCalendarSystem(fastTime);
            cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime,
                                                            TimeZone.getDefaultRef());
        }
        return cdate;
    }
    
    /**
     * 将对象的状态写入到流中
     *
     * @serialData getTime()返回是一个long型量
     *            相对于January 1, 1970, 00:00:00 GMT毫秒值偏移量.
     */
    private void writeObject(ObjectOutputStream s)
         throws IOException
    {
        s.writeLong(getTimeImpl());
    }

    /**
     * 从数据流中重新创建时间
     */
    private void readObject(ObjectInputStream s)
         throws IOException, ClassNotFoundException
    {
        fastTime = s.readLong();
    }
}

```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值