关于java中的Date类以及用java.time包下的替代Date的记录

一、JDK中关于java.util.Date类的说明

首先,看看在jdk中的javadoc关于java.util.Date类的说明

/**
 * The class <code>Date</code> represents a specific instant
 * in time, with millisecond precision.
 * <p>
 * Prior to JDK&nbsp;1.1, the class <code>Date</code> had two additional
 * functions.  It allowed the interpretation of dates as year, month, day, hour,
 * minute, and second values.  It also allowed the formatting and parsing
 * of date strings.  Unfortunately, the API for these functions was not
 * amenable to internationalization.  As of JDK&nbsp;1.1, the
 * <code>Calendar</code> class should be used to convert between dates and time
 * fields and the <code>DateFormat</code> class should be used to format and
 * parse date strings.
 * The corresponding methods in <code>Date</code> are deprecated.
 * <p>
 * Although the <code>Date</code> class is intended to reflect
 * coordinated universal time (UTC), it may not do so exactly,
 * depending on the host environment of the Java Virtual Machine.
 * Nearly all modern operating systems assume that 1&nbsp;day&nbsp;=
 * 24&nbsp;&times;&nbsp;60&nbsp;&times;&nbsp;60&nbsp;= 86400 seconds
 * in all cases. In UTC, however, about once every year or two there
 * is an extra second, called a "leap second." The leap
 * second is always added as the last second of the day, and always
 * on December 31 or June 30. For example, the last minute of the
 * year 1995 was 61 seconds long, thanks to an added leap second.
 * Most computer clocks are not accurate enough to be able to reflect
 * the leap-second distinction.
 * <p>
 * Some computer standards are defined in terms of Greenwich mean
 * time (GMT), which is equivalent to universal time (UT).  GMT is
 * the "civil" name for the standard; UT is the
 * "scientific" name for the same standard. The
 * distinction between UTC and UT is that UTC is based on an atomic
 * clock and UT is based on astronomical observations, which for all
 * practical purposes is an invisibly fine hair to split. Because the
 * earth's rotation is not uniform (it slows down and speeds up
 * in complicated ways), UT does not always flow uniformly. Leap
 * seconds are introduced as needed into UTC so as to keep UTC within
 * 0.9 seconds of UT1, which is a version of UT with certain
 * corrections applied. There are other time and date systems as
 * well; for example, the time scale used by the satellite-based
 * global positioning system (GPS) is synchronized to UTC but is
 * <i>not</i> adjusted for leap seconds. An interesting source of
 * further information is the U.S. Naval Observatory, particularly
 * the Directorate of Time at:
 * <blockquote><pre>
 *     <a href=http://tycho.usno.navy.mil>http://tycho.usno.navy.mil</a>
 * </pre></blockquote>
 * <p>
 * and their definitions of "Systems of Time" at:
 * <blockquote><pre>
 *     <a href=http://tycho.usno.navy.mil/systime.html>http://tycho.usno.navy.mil/systime.html</a>
 * </pre></blockquote>
 * <p>
 * In all methods of class <code>Date</code> that accept or return
 * year, month, date, hours, minutes, and seconds values, the
 * following representations are used:
 * <ul>
 * <li>A year <i>y</i> is represented by the integer
 *     <i>y</i>&nbsp;<code>-&nbsp;1900</code>.
 * <li>A month is represented by an integer from 0 to 11; 0 is January,
 *     1 is February, and so forth; thus 11 is December.
 * <li>A date (day of month) is represented by an integer from 1 to 31
 *     in the usual manner.
 * <li>An hour is represented by an integer from 0 to 23. Thus, the hour
 *     from midnight to 1 a.m. is hour 0, and the hour from noon to 1
 *     p.m. is hour 12.
 * <li>A minute is represented by an integer from 0 to 59 in the usual manner.
 * <li>A second is represented by an integer from 0 to 61; the values 60 and
 *     61 occur only for leap seconds and even then only in Java
 *     implementations that actually track leap seconds correctly. Because
 *     of the manner in which leap seconds are currently introduced, it is
 *     extremely unlikely that two leap seconds will occur in the same
 *     minute, but this specification follows the date and time conventions
 *     for ISO C.
 * </ul>
 * <p>
 * In all cases, arguments given to methods for these purposes need
 * not fall within the indicated ranges; for example, a date may be
 * specified as January 32 and is interpreted as meaning February 1.
 *
 * @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>

翻译+总结:

Date类表示的是一个特定的时刻,精度为毫秒。在jdk1.1之前,支持解释为年、月、日、时、分、秒的值,也支持格式化和解析日期字符串,但因为适合国际化,所以在jdk1.1之后,这些方法就被弃用了。jdk1.1之后,日期格式化需要用到DateFormat,日期转换上则需要使用Calendar。

闰秒:几乎所有现有现在的操作系统都假设1天=24*60*60=86400秒,然而在UTC中,大约每隔一两年就会出现一次额外的秒,称为“闰秒”。闰秒总是添加为当天的最后一秒,并且总是在12月31日或6月30日。例如,因为添加了闰秒,1995年的最后一分钟长61秒。大多数计算机时钟都不够准确,无法反应闰秒的级别。

几个概念:

GMT:格林威治标准时间;

UT:世界时间;

UTC和UT之间的区别:UTC基于原子钟,UT基于天文观测;

UT1:应用了某些修正的UT版本。

根据需要,在UTC中引入闰秒,使得UTC与UT1的误差保持一0.9秒以内。

在Date类中:

年份,是从1900年开始的一个整数;

月份,是用0-11表示的一个整数,0表示一月,1表示二月,依此类推;

日期,由1-31之间的整数表示;

时,由0-23之间的整数表示;

分:由0-59之间的整数表示;

秒:由0-61之间的整数表示,值60和61仅在闰秒时出现(前提当然是支持的java实现中,由于闰秒的引入方式,同一分种内出现两个闰秒的可能性极小,但遵循ISOC的日期和时间约定)

:在所有情况下,用于这些目的的方法的参数不必落在指定的范围内(例如:1月32日,会被解释为2月1日,并不会报错!!!)

看看Date类中的方法,确实跟年月日时分秒相关的,都已标记为Deprecated:

(贴个图吧,一目了然)

再来,细看看它的一些方法:

比如:

getDate():返回的是一个月中的第几天(1-31)

/**
     * Returns the day of the month represented by this <tt>Date</tt> object.
     * The value returned is between <code>1</code> and <code>31</code>
     * representing the day of the month that contains or begins with the
     * instant in time represented by this <tt>Date</tt> object, as
     * interpreted in the local time zone.
     *
     * @return  the day of the month represented by this date.
     * @see     java.util.Calendar
     * @deprecated As of JDK version 1.1,
     * replaced by <code>Calendar.get(Calendar.DAY_OF_MONTH)</code>.
     * @deprecated
     */
    @Deprecated
    public int getDate() {
        return normalize().getDayOfMonth();
    }

getDay():返回的是一周中的第几天(0-6,0表示Sunday,6表示Saturday)

/**
     * Returns the day of the week represented by this date. The
     * returned value (<tt>0</tt> = Sunday, <tt>1</tt> = Monday,
     * <tt>2</tt> = Tuesday, <tt>3</tt> = Wednesday, <tt>4</tt> =
     * Thursday, <tt>5</tt> = Friday, <tt>6</tt> = Saturday)
     * represents the day of the week that contains or begins with
     * the instant in time represented by this <tt>Date</tt> object,
     * as interpreted in the local time zone.
     *
     * @return  the day of the week represented by this date.
     * @see     java.util.Calendar
     * @deprecated As of JDK version 1.1,
     * replaced by <code>Calendar.get(Calendar.DAY_OF_WEEK)</code>.
     */
    @Deprecated
    public int getDay() {
        return normalize().getDayOfWeek() - BaseCalendar.SUNDAY;
    }

        getDate(),getDay(),如果从字段意思上理解,可能会有误导吧?!!!

        另外还有一个:java.sql.Date 继承自 java.util.Date,同样都起名为Date,这个也不知道意图何在!!!

二、用java.time包下的类替代Date

        都在说Date的不好,且被大佬们安利,所以决定用java.time包中的类来替代Date,虽然不存在什么难度,但影响不小,使用面太广,改起来都是工作量~~~

        既然要改,那首先得明确下,用Date的场景有哪些吧?大概率不是简单的ctrl+f替换就能解决的!

        从Date的定义中看,它表示的是一个时间上瞬间,并不是一个日期,也没有时区、格式、日历系统。那么,针对不同的场景,可以有不同的api替换,如:

        表示时间上的瞬间,可以用java.time.Instant来替代;

        表示日期和时间,可以用java.time.LocalDateTime来替代;

        表示日期,可以用java.time.LocalDate替代;

        表示时间,可以用java.time.LocalTime替代;

        和时区相关的,可以用java.time.ZonedDateTime(类似于Calendar);

Show The Code...

Date/Calendar的实现:

//Date、Calendar表示当前时间,当前瞬时时间
Date date = new Date();
Date nowDateCalendar = Calendar.getInstance().getTime();

java.time

//java.time包中的实现
Instant nowInstant = Instant.now(); //表示当前时间,瞬间
LocalDateTime localDateTime = LocalDateTime.now(); //表示日期,没有时区,不能直接转换为时间戳
ZonedDateTime zonedDateTime = ZonedDateTime.now(); //表示日期,有时区

//Date与Instant的转换
Date nowDateFromInstant = Date.from(nowInstant); //instant转换为Date,为方便使用Date相关的api
Timestamp nowTsFromInstant = Timestamp.from(nowInstant); //instant转为Timestamp,为方便使用Timestamp相关的api

三、常用到的一些方法的转换记录

日期格式转换相关:(时间格式化)

在Date中的实现,借助于SimpleDateFormat

/**
 * Date类中的格式化方法
 * @param date
 * @param fommat
 * @return
 */
public static String formatDate(Date date, String fommat) {
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(fommat);
    return simpleDateFormat.format(date);//调用sdf.format方法进行格式化处理
}

在java.time中的实现,借助DateTimeFormatter,但format方法为日期类所有

/**
 * java.time中的格式化方法
 * @param date
 * @param format
 * @return
 */
public static String formatDate(LocalDateTime date, String format) {
    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(format);
    return date.format(dateTimeFormatter);//注意区别,format为LocalDateTime实例的方法;
}

日期修改相关:addSeconds/addMinutes/addHours/addDays/addMonths/addYears

在Date中的实现,需要借助Calendar

/**
 * 增加秒数
 * @param date
 * @param seconds
 * @return
 */
public static Date addSeconds(Date date, int seconds) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.SECOND, seconds); //注意,这里使用的是Calendar的add方法,第一个参数为field,第二个参数为add的值,下同
    return calendar.getTime();
}
/**
 * 增加分钟数
 * @param date
 * @param minutes
 * @return
 */
public static Date addMinutes(Date date, int minutes) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.MINUTE, minutes);
    return calendar.getTime();
}
/**
 * 增加小时数
 * @param date
 * @param hours
 * @return
 */
public static Date addHours(Date date, int hours) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.HOUR, hours);
    return calendar.getTime();
}
/**
 * 增加天数
 * @param date
 * @param days
 * @return
 */
public static Date addDays(Date date, int days) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.DATE, days);
    return calendar.getTime();
}

/**
 * 增加月数
 * @param date
 * @param months
 * @return
 */
public static Date addMonths(Date date, int months) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.MONTH, months);
    return calendar.getTime();
}
/**
 * 增加年数
 * @param date
 * @param years
 * @return
 */
public static Date addYears(Date date, int years) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(Calendar.YEAR, years);
    return calendar.getTime();
}

在java.time中的实现,就简单多了

/**
 * 增加秒数
 * @param date
 * @param seconds
 * @return
 */
public static LocalDateTime addSeconds(LocalDateTime date, int seconds) {
    return date.plusSeconds(seconds);//注意,这里使用的是LocalDateTime的plus方法,plusXXX,直接调用相关api即可,其他类似
//        return date.plusMinutes(minutes);
//        return date.plusHours(hours);
//        return date.plusDays(days);
//        return date.plusMonths(months);
//        return date.plusYears(years);
}

关于获取一天中的开始、结束时间、一周中的第几天:

在Date中的实现:

/**
 * 获取当天的开始时间
 * @param date
 * @return
 */
public static Date getStartTimeOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    return calendar.getTime();
}
/**
 * 获取当天的结束时间
 * @param date
 * @return
 */
public static Date getEndTimeOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.HOUR_OF_DAY, 23);
    calendar.set(Calendar.MINUTE, 59);
    calendar.set(Calendar.SECOND, 59);
    calendar.set(Calendar.MILLISECOND, 999);
    return calendar.getTime();
}
/**
 * 获取星期几
 * @param date
 * @return
 */
public static String getDayOfWeek(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
    return "星期" + dayOfWeek;
}

在java.time中的实现:

/**
 * 获取当天的开始时间
 * @param date
 * @return
 */
public static LocalDateTime getStartTimeOfDay(LocalDateTime date) {
    return date.toLocalDate().atStartOfDay();
//        return date.withHour(0).withMinute(0).withSecond(0).withNano(0);
}
/**
 * 获取当天的结束时间
 * @param date
 * @return
 */
public static LocalDateTime getEndTimeOfDay(LocalDateTime date) {
    return date.toLocalDate().atTime(LocalTime.MAX);
//        return date.withHour(23).withMinute(59).withSecond(59).withNano(999);
}   
/**
 * 获取星期几
 * @param date
 * @return
 */
public static String getDayOfWeek(LocalDateTime date) {
    DayOfWeek dayOfWeek = date.getDayOfWeek();
    return "星期" + dayOfWeek;
}

LocalDateTime中atStartOfDay的实现:

LocalTime中的MIN,MAX,MIDNIGHT,NOON定义:

日期比较相关:(用一个例子包含before和after)

在Date中的实现:

/**
 * 判断日期是否在两个日期之间
 * @param date
 * @param start
 * @param end
 * @return
 */
public static boolean isBetween(Date date, Date start, Date end) {
    return date.after(start) && date.before(end);
}

在java.time中的实现:

/**
 * 判断日期是否在两个日期之间
 * @param date
 * @param start
 * @param end
 * @return
 */
public static boolean isBetween(LocalDateTime date, LocalDateTime start, LocalDateTime end) {
    return date.isAfter(start) && date.isBefore(end);
}
/**
 * 判断日期是否在两个日期之间
 * @param date
 * @param start
 * @param end
 * @return
 */
public static boolean isBetween(Instant date, Instant start, Instant end) {
    return date.isAfter(start) && date.isBefore(end);
}

打平!!!

完~~~

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值