@[TOC]
在做项目中入数据库的时候,碰到的问题:
需要获取系统时间,并且获取系统 24h 后的时间(作为数据的失效时间)
文后将用 Java8 的时间 API 给出这个问题的方案
Date 类
Date 类主要封装了系统的日期和时间的信息,表示系统的特定时间戳,可以精确到毫秒。Date 对象表示时间的默认顺序是星期、月、日、小时、分、秒、年。
构造方法
Java8 的构造方法使用下来这两个,Date() + Date(long date) ;其他的构造方法都被标记为:@Deprecated
public Date() { this(System.currentTimeMillis()); } //所以当我们只需要使用毫秒时,我们可以直接使用 System.currentTimeMillis() public Date(long date) { fastTime = date; } // 上面的构造函数最终也是调用下面的构造函数,
Date()
使用此构造方法分配的对象可以获取本地的当前时间(精确到秒)
Date date = new Date();
System.out.println(date);
//Thu Aug 01 20:54:32 CST 2019
simpleDateFormat
//格式化,可以转换成我们想要的任意格式
Date date = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(df.format(date));
//2019-08-01 20:59:19
Date(long date)
此种形式表示从 GMT 时间(格林尼治时间)1970年1月1日0时0分0秒开始经过参数 date 指定的毫秒数。
Date date = new Date(1000);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
System.out.println(df.format(date));
//1970-01-01 08:00:01
为什么小时是 08,而不是 00;因为使用 CST(China Standard Time)时区的时间,刚好比格林尼治时间多 8 个小时
常用方法
long getTime():返回子1970.1.1.00:00:00 GMT 以来,此 Date 对象表示的毫秒数。
Boolean after(Date when):判断此日期是否在指定日期之后
Boolean before(Date when):判断此日期是否在指定日期之前
Calendar 类
Calendar 类是一个抽象类,它为特定瞬间与 YEAR、MONTH、DAY_OF_MONTH、HOUR 等日历字段之间的转换提供了一些方法,并为之操作日历字段(如获得下星期日的日期)提供了一些方法。
创建 Calender 对象不能使用 new 关键字「抽象类」,但是它提供了一个 getInstance() 方法来获得 Calendar 类对象。
getInstance() 方法(静态方法)返回一个 Calendar 对象,其日历字段已由当前日期和时间初始化。
Calendar calendar = Calendar.getInstance();
System.out.println(calendar);
System.out.println(calendar.getTime());
//
下面是打印 calendar 的结果:
java.util.GregorianCalendar[time=1577415516152,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=29,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2019,MONTH=11,WEEK_OF_YEAR=52,WEEK_OF_MONTH=4,DAY_OF_MONTH=27,DAY_OF_YEAR=361,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=4,AM_PM=0,HOUR=10,HOUR_OF_DAY=10,MINUTE=58,SECOND=36,MILLISECOND=152,ZONE_OFFSET=28800000,DST_OFFSET=0]
Fri Dec 27 10:58:36 CST 2019
常用方法
int get(int field) :返回指定日历字段的值
Calendar calendar = Calendar.getInstance();
System.out.println(calendar.get(Calendar.YEAR));
//2019
//Calendar#getTime 源码;就是调用了 Date 的构造函数
public final Date getTime() {
return new Date(getTimeInMillis());
}
Date getTime():返回一个表示此 Calendar 时间值(从格林威治时间 1970.01.01.00:00:00 到现在的毫秒偏移量)的Date对象
格式化时间
SimpleDateFormat:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//可指定任意的格式
java 8 时间API
日期时间
//获取当前日期
System.out.println(LocalDate.now()); //打印:2019-12-27
//获取当前时间
System.out.println(LocalTime.now()); //打印:11:19:28.735
//获取当前日期+时间
System.out.println(LocalDateTime.now()); //打印:2019-12-27T11:21:06.145
LocalDate
在 ISO-8601 日历系统中没有时区的日期;如 2019-12-27
此类不可变,并且是线程安全的
// 创建 LocalDate 的两种实例方式:
LocalDate localDate1=LocalDate.now();
LocalDate localDate2=LocalDate.of(1996,12,10);
// LocalDate localDate3=LocalDate.of(1996, Month.OCTOBER,10); Month 也可这样(枚举)
System.out.println(localDate1+" "+localDate2);
// 2019-12-29 1996-12-10
将时间加/减一天
LocalDate localDate1 = LocalDate.now().plusDays(1);
localDate1.minusDays(1);
LocalDate localDate11 = localDate1.minusDays(1);
System.out.println(localDate1);
System.out.println(localDate11);
/**
2019-12-30
2019-12-29
为什么中间已经将当天加上的时间减去了,再减一次,应该是比今天(当前)时间少一天才对啊
因为,LocalDate 是被 final 修饰的(和 String 一样),我们去改动它,原来引用保存的对象还是不变,会 新生成一个 LocalDate 对象原来操作的对像内容不变。
*/
解答开篇:
LocalDate localDate1 = LocalDate.now().plusDays(1); //加一天
LocalDate localDate1 = LocalDate.now().minusDays(1); //减一天
我们有时候和数据库判断,如果只需要精确到天数,那么这个就可以了。
LocalTime
在 ISO-8601 日历系统中没有时区的时间
此类不可变,并且也是线程安全的
// 创建 LocalTime 实例的两种方式:
LocalTime localTime1=LocalTime.now();
LocalTime localTime2=LocalTime.of(15,59,10);
System.out.println(localTime1+" "+localTime2);
// 15:13:52.009 15:59:10
从打印出来的形式,知道 LocalTime 支持毫秒
此时如果与数据库时间交互,需要精确到小时、分钟、秒,则需要此类(不过一般过期啥的都是整天吧)
LocalTime localTime1 = LocalTime.of(23,30);
LocalTime localTime2 = localTime1.plusHours(8);
// 晚上休息8个小时
System.out.println(localTime1 +" "+ localTime2);
// 23:30 07:30
LocalDateTime
在 ISO-8601 日历系统中没有时区的日期时间
此类不可变,并且也是线程安全的
//创建 LocalDateTime 实例的方式
LocalDateTime localDateTime1 = LocalDateTime.now();
LocalDateTime localDateTime2 = LocalDateTime.of(2019, 12, 10, 15, 37, 50);
System.out.println(localDateTime1 + " " + localDateTime2);
//2019-12-29T15:37:49.283 2019-12-10T15:37:50
支持毫秒,此类的也是有各种可以调整时间的函数,从年到毫秒都有
ZoneDateTime
在 ISO-8601 日历系统中带有时区的日期时间
此类不可变,并且也是线程安全的
ZonedDateTime zonedDateTime1 = ZonedDateTime.now();
ZoneId zoneId = ZoneId.of("Asia/Shanghai");
ZonedDateTime zonedDateTime2 = ZonedDateTime.of(2019,12,10,4,2,1,1, zoneId);
System.out.println(zonedDateTime1 + " " + zonedDateTime2);
//2019-12-29T15:31:40.921+08:00[Asia/Shanghai]
//2019-12-10T04:02:01.000000001+08:00[Asia/Shanghai]
此类的也是有各种可以调整时间的函数,从年到毫秒都有
DateTimeFormatter
格式化日期时间,不可变且线程安全
String sminus = LocalDateTime.now().minusDays(2).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
String splus = LocalDateTime.now().plusDays(1).format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"));
System.out.println(sminus + " " + splus);
// 后面是格式化日期:方便入库
// 2019-12-27 15:41:11 2019/12/30 15:41:11
总结
对于我们在系统中经常会存储时间到数据库
以前:
new date() 后必须用 simpleDateFormat 格式化,而且一般有 只有“日期”和“日期时间”两个格式
Java8:
LocalDate.now() 直接就是数据库中存储“日期”得格式
“日期时间”则需要 DateTimeFormatter 格式化。
上面讲到的 Java8 时间API,当然都是 Java8 才引入的,以前 JDK 版本不可用。
都是:
- 被 final 修饰,不可修改
- 线程安全
tips:JDBC 映射日期类型
SQL ——> java
date——>LocalDate
time——> LocalTime
timestamp——>LocalDateTime