一、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 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 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 day =
* 24 × 60 × 60 = 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> <code>- 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);
}
打平!!!
完~~~