表示时间上的特定瞬间,精确到毫秒,但是本身不具备时间属性,只是精度精确到了毫秒。
java.util.Date 是java.sql.Date、java.sql.Time、java.sql.Timestamp的父类,所以他们四个类中有很多相同的方法。
在JDK 1.1之前,类 Date具有两个附加的函数。它允许将日期解释为年,月,日,小时,分钟和秒值。它还允许格式化和解析日期字符串。不幸的是,这些功能的API不适合国际化。从JDK1.1开始,应该使用 Calendar类在日期和时间之间进行转换和DateFormat类应用于格式化和解析日期字符串。
引自JDK1.8
构造方法:
java.util.Date utildate=new java.util.Date();
System.out.println(utildate);
// 系统打印:Mon May 25 09:25:57 CST 2020
// 自动获取系统时间
java.util.Date utildate=new java.util.Date(long date);
// If the millisecond date value contains time info, mask it out.
// 如果毫秒日期值包含时间信息,则将其屏蔽掉。
// 使用指定毫秒数作为参数,使该utildate表示一个特定的时间瞬间
// 毫秒数是指从标准基准时间(称为“历元(epoch)”,即 1970 年 1 月 1 日 00:00:00 GMT)以来到这个特定时间瞬间一共有多少毫秒,long类型
public Date(int year, int month, int day)
// year the year minus 1900; must be 0 to 8099. (Note that 8099 is 9999 minus 1900.)
// 意思就是年份 year 由整数 year + 1900 表示。
// month 0 to 11
// day 1 to 31
// 已过时,推荐使用上面的构造方法!
// 示例:
java.sql.Date sqldate2=new java.sql.Date(2000,0,1);
System.out.println(sqldate2);
// 系统打印:3900-01-01
常用方法:
public long getTime()
// 返回自 1970 年 1 月 1 日 00:00:00 GMT 以来到此 Date 对象表示的时间瞬间中间经过的毫秒数。
// 示例:
java.util.Date utildate=new java.util.Date();
System.out.println(utildate.getTime());
// 系统打印:1590371623129
public void setTime(long time)
// 使该Date对象表示一个特定的时间瞬间,参数是该时间瞬间从1970 年 1 月 1 日 00:00:00 GMT到这个时间瞬间所经过的毫秒数
public boolean before(Date when)
// 测试此日期是否早于指定日期
public boolean after(Date when)
// 测试此日期是否在指定日期之后
public boolean equals(Object obj)
// 比较两个日期是否相等
public String toString ()
// 以日期转义格式yyyy-mm-dd格式化日期。
// @return a String in yyyy-mm-dd format
// 示例:
java.util.Date utildate=new java.util.Date();
System.out.println(utildate.toString());
// 系统打印:Mon May 25 14:34:30 CST 2020
构造方法
public Time(int hour, int minute, int second)
// 继承自java.util.Date的构造方法
// 已过时,不再使用,推荐使用下面的方法
public Time(long time)
// 示例:
java.util.Date utildate=new java.util.Date();
java.sql.Time sqltime=new java.sql.Time(utildate.getTime());
System.out.println(sqltime);
// 系统打印:20:13:06
常用方法:
public void setTime(long time)
// 使用毫秒的时间值设置 Time code>对象
public static Time valueOf(String s)
// 将JDBC时间转义格式的字符串转换为Time
// time in format "hh:mm:ss"
// 示例:
java.sql.Time sqltime1=Time.valueOf("21:56:44");
System.out.println(sqltime1);
// 系统打印:21:56:44
构造方法:
public Date(int year, int month, int day)
// 继承自java.util.Date的构造方法:
// 已过时,不再使用,推荐使用下面的方法
java.sql.Date sqldate=new java.sql.Date(long date);
// If the millisecond date value contains time info, mask it out.
// 如果毫秒日期值包含时间信息,则将其屏蔽掉。
// 使用指定毫秒数作为参数,使该sqldate表示一个特定的时间瞬间
// 毫秒数是指从标准基准时间(称为“历元(epoch)”,即 1970 年 1 月 1 日 00:00:00 GMT)以来到这个特定时间瞬间一共有多少毫秒,long类型
// 示例:
java.util.Date utildate=new java.util.Date();
// 先实例化一个utildate对象,会自动调用系统当前时间注入该对象。
java.sql.Date sqldate=new java.sql.Date(utildate.getTime());
// 使用utildate.getTime()方法获取系统当前时间距离历元的毫秒数,使用此毫秒数作为参数实例化一个java.sql.Date对象
System.out.println(sqldate);
// 系统打印:2020-05-25
常用方法:
public void setTime(long date)
// 如果毫秒日期值包含时间信息,则将其屏蔽掉。
// 使该Date对象表示一个特定的时间瞬间,参数是该时间瞬间从1970 年 1 月 1 日 00:00:00 GMT到这个时间瞬间所经过的毫秒数
public long getTime()
// 返回此 Date 对象所表示的时间瞬间距 1970 年 1 月 1 日 00:00:00 GMT 以来的毫秒数。
// 示例:
java.util.Date utildate=new java.util.Date();
java.sql.Date sqldate=new java.sql.Date(utildate.getTime());
System.out.println(sqldate.getTime());
// 系统打印:1590371623129
其他从java.util.Date继承的诸如getDate、getMonth、getMinutes(SQL Date本身就没有时间部分)等方法已经被弃用,从JDK1.1开始,被Calendar.get(Calendar.DAY_OF_MONTH)替代。
构造方法:
public Timestamp(long time)
// 使用指定毫秒数作为参数,使该Timestamp表示一个特定的时间瞬间
// 毫秒数是指从标准基准时间(称为“历元(epoch)”,即 1970 年 1 月 1 日 00:00:00 GMT)以来到这个特定时间瞬间一共有多少毫秒,long类型
// 示例:
java.util.Date utildate=new java.util.Date();
Timestamp timestamp=new Timestamp(utildate.getTime());
System.out.println(timestamp);
// 系统打印:2020-05-25 15:51:35.063
常用方法:
public void setTime(long time)
public long getTime()
public String toString ()
以上方法都是比较常见的,继承自java.util.Date,不再详细说明。
public void setNanos(int n)
// 设置此 Timestamp 对象的 nanos 值
public int getNanos()
// 获取此 Timestamp 对象的 nanos 值
public boolean equals(Timestamp ts)
// 测试此对象是否等于给定的 Timestamp 对象
public boolean before(Timestamp ts)
// 测试此 Timestamp 对象是否早于给定的 Timestamp 对象。
public boolean after(Timestamp ts)
// 测试此 Timestamp 对象是否晚于给定的 Timestamp 对象。
public int compareTo(Timestamp ts)
// 将此 Timestamp 对象与给定 Timestamp 对象相比较,大于返回1,小于返回-1,相等返回0
public static Timestamp valueOf(LocalDateTime dateTime)
// 从给定的LocalDateTime中提取属性转义给一个Timestamp对象,此方法会return new Timestamp
可以理解为Date和String之间的桥梁,通过用户自定义的日期-时间格式完成Date和String之间的转换。
字符 | 含义 | 示例 |
---|---|---|
y | 年 | yyyy > 2020 |
M | 月 | MM > 05 |
d | 日 | dd > 25 |
E | 星期 | E > 星期一 |
a | 上下午 | a > 下午(PM) |
H | 24进制小时 | HH:mm:ss > 16:28:31 |
h | 12进制小时 | |
m | 分 | |
s | 秒 |
构造方法:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
常用方法:
Date转字符串
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
java.util.Date utildate=new java.util.Date();
String dateStringParse = sdf.format(utildate);
System.out.println(dateStringParse);
// 系统打印:2020-05-25 17:33:08
字符串转Date
String dateString = "2017-12-20 14:02:08";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date dateParse = sdf.parse(dateString);
System.out.println(dateParse);
// 系统打印:Mon May 25 17:02:08 CST 2020
灵活使用:
SimpleDateFormat myFmt = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
SimpleDateFormat myFmt1 = new SimpleDateFormat("yy/MM/dd HH:mm");
SimpleDateFormat myFmt2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//等价于now.toLocaleString()
SimpleDateFormat myFmt3 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒 E ");
SimpleDateFormat myFmt4 = new SimpleDateFormat("一年中的第 D 天 一年中第w个星期 一月中第W个星期 在一天中k时 z时区");
Date now = new Date();
System.out.println(myFmt.format(now));
System.out.println(myFmt1.format(now));
System.out.println(myFmt2.format(now));
System.out.println(myFmt3.format(now));
System.out.println(myFmt4.format(now));
// 系统打印:
//2020年05月25日 18时42分41秒
// 20/05/25 18:42
// 2020-05-25 18:42:41
// 2020年05月25日 18时42分41秒 星期一
// 一年中的第 146 天 一年中第22个星期 一月中第5个星期 在一天中18时 CST时区
脚下留心:
创建 SimpleDateFormat 对象时必须指定转换格式。
使用sdf.parse(dateString)方法时必须对ParseException抛出或者使用Try,catch捕获。
SimpleDateFormat并不是一个线程安全的类,在多线程情况下,会出现异常。
java.util.Calendar 类用于封装日历信息,其主要作用在于方便操作日历字段,例如获得一星期后是星期几,亦可以设置和获取日期数据的特定部分,如小时,分钟,并提供在日期上加上或减去一些值。
构造方法:
Calendar calendar = Calendar.getInstance();
// Calendar是一个抽象类,所以只能通过此途径获取一个Calendar对象,而不能直接创建
// 使用默认时区和区域设置获取日历,会自动注入时间
常用方法:
public void set(int year,int month,int date,int hourofday,int minute,int second)
// 设置日历的年、月、日、时、分、秒。
public int get(int field)
// 返回给定日历字段的值。所谓字段就是年、月、日等等
// 示例:
System.out.println(calendar.get(Calendar.YEAR));
// 系统打印:2020
public void setTime(Date date)
// 使用给定的Date设置此日历的时间
public final Date getTime()
// 返回一个Date表示此日历的时间
// 示例:
Calendar calendar = Calendar.getInstance();
Date utildate = calendar.getTime();
System.out.println(utildate);
// 系统打印:Mon May 25 18:24:32 CST 2020
abstract public void add(int field, int amount)
// 按照日历的规则,给指定字段添加或减少时间量
// 示例:
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR,1);
System.out.println(calendar.getTime());
// 系统打印:Tue May 25 18:30:33 CST 2021
// 当前时间是2020年,调用calendar.add(Calendar.YEAR,1)给年的字段加了一年
public long getTimeInMillies()
// 以毫秒为单位返回该日历的时间值。
// 示例:
Calendar calendar = Calendar.getInstance();
System.out.println(calendar.getTimeInMillis());
// 系统打印:1590406546161
java.util.Date是被广为诟病的,实际开发中尽量少用,java.sql.Time、java.sql.Date、Timestamp这三个类在涉及与数据库交互时,需要使用,三者精度各不相同,选取相应的符合业务逻辑的即可,例如仅需要记录时间,不需要记录精确的日期,选择java.sql.Time即可,而Calendar侧重于对日期的操作,例如算一年后,7天后等等,且可以单独对某个字段操作,推荐使用。
脚下留心:
绝大部分类的month都是从0开始的,实际输出时,需要+1
名称 | 描述 |
---|---|
格式 | YYYY-MM-DD |
范围 | 1601-01-01 到 9999-01-01 |
适用场景 | 仅需要精确到天的业务场景 |
名称 | 描述 |
---|---|
格式 | YYYY-MM-DD HH:mm:ss |
范围 | 1001-01-01 00:00:00 到 9999-12-31 23:59:59 |
适用场景 | 业务需要精确到秒时 |
名称 | 描述 |
---|---|
格式 | YYYY-MM-DD HH:mm:ss |
范围 | 1970-01-01 00:00:01 到 2038-01-19 03:14:07 |
适用场景 | 业务需要精确到秒或者毫秒时,或是系统部署于不同时区 |
名称 | 描述 |
---|---|
格式 | HH:mm:ss |
范围 | 00:00:00 到 23:59:59 |
适用场景 | 业务仅仅需要记录每天的时间时 |
Date,DateTime,Time没什么好比较的,按照自己实际的业务需求,选择合适的精度就可以了。
重点看一下DateTime和TimeStamp,大家都是年月日时分秒,如何取舍呢?
1.应用场景不同,这是最大的区别,如果服务器部署于不同的时区(即国内外),这时如果使用DateTime就会出现各种问题,需要使用TimeStamp。
2.存储方式不同,TimeStamp将插入的世界从当前时区转换为UTC(世界标准时间)进行存储,而查询时又转换回来。而DateTime则不做任何改变,基本上是原样输入和输出。
什么是UTC(GMT)?
协调世界时,又称世界统一时间、世界标准时间、国际协调时间。
其不属于任何一个时区,中国大陆、中国香港、中国澳回门、中国台湾、蒙古国、新加坡、马来西亚、菲律宾、西澳大利亚州的标准时间与UTC的时差均为+8,也就是UTC+8。
时区:
地球自西向东旋转,东边比西边先看到太阳,东边的时间也比西边的早。为了统一世界的时间,1884年的国际经度会议规规定将全球划分为24个时区(东、西各12个时区)。规定英国(格林尼治天文台旧址)为零时区(GMT+00),东1-12区,西1-12区,中国北京处于东8区(GMT+08)。
若英国时间为6点整,则GMT时间为6点整,则北京时间为14点整。
GMT:
格林尼治标准时间,和UTC一般视为无差,UTC是以原子时计时,更加精准,适应现代社会的精确计时,而GMT是根据地球的自转和公转来计算时间,会有一点点误差。
下面都是 MySQL 允许的形式,插入表时MySQL 会自动处理
2016-10-01 20:48:59
2016#10#01 20/48/59
20161001204859
Java类型 | MySql类型 | Java注入数据库 |
---|---|---|
date | date | YES |
date | time | NO |
date | timestamp | NO |
date | datetime | NO |
time | date | NO |
time | time | YES |
time | timestamp | NO |
time | datetime | NO |
timestamp | date | YES |
timestamp | time | YES |
timestamp | timestamp | YES |
timestamp | datetime | YES |
总结,如果从Java注入的格式完全包含了MySql的格式,则可以注入。
MySql类型 | Java类型 | 数据库注入JavaBean |
---|---|---|
date | date | YES |
date | time | YES 缺少用历元 |
date | timestamp | YES 缺少用历元 |
time | date | YES 缺少用历元 |
time | time | YES |
time | timestamp | YES 缺少用历元 |
timestamp | date | YES |
timestamp | time | YES |
timestamp | timestamp | YES |
datetime | date | YES |
datetime | time | YES |
datetime | timestamp | YES |
总结:均不会出错,但是缺少的部分会使用历元填充。