一、获取系统当前时间
想获取系统当前时间,System类中的静态方法currentTimeMillis()想必大家都不会陌生,它返回的是当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差,也被称为时间戳。
二、java.util.Date类与java.sql.Date类
关于这两个类,很多人可能不是特别清楚两者之间的区别与联系,接下来我们对此进行简单的梳理。
- 区别:
首先,从包名可以看出java.sql.Date类是与数据库相关的类,更准确地来说,它与数据库中的日期类型变量相对应。而java.util.Date类,就是我们平时使用的类了(事实上开发中也很少会用它,具体后面再说)。
那么除了根据包名能判断出的这些外,两者之间有什么联系呢?
- 联系:
通过查阅jdk源码可知:java.sql.Date继承了java.util.Date类,也就是说,java.sql.Date类是java.util.Date类的子类。
搞清楚了两者之间的区别和联系后,我们来回答两个问题:
- 第一个问题:如何将java.sql.Date对象转换为java.util.Date对象呢?
熟悉面向对象的读者肯定知道,子类对象可直接向上转型成父类对象(多态性)。据此,我们可以直接将java.sql.Date类的对象赋给java.util.Date对象,代码如下:
.util.Date date = new java.sql.Date(136513463156L); //向java.sql.Date的构造器中传入时间戳
- 第二个问题:如何将java.util.Date对象转换为java.sql.Date对象呢?
进行强制类型转换?当然不可行。事实上,如果我们将父类对象强制转化为子类对象,将会抛出Exception in thread "main" java.lang.ClassCastException: java.util.Date cannot be cast to java.sql.Date异常。那么就只能从两者之间的联系入手,代码如下:
java.util.Date date = new java.util.Date();// 创建java.util.Date对象
java.sql.Date sqlDate = new java.sql.Date(date.getTime());//getTime()方法会返回当前Date对象对应的毫秒数。(时间戳)
补充说明(了解即可):
- java.text.SimpleDataFormat类:主要用来格式化日期时间。简单介绍一下用法:
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//格式化
String format = sdf.format(date);
System.out.println(format);//2019-02-18 11:48:27
//解析:要求字符串必须是符合SimpleDateFormat识别的格式(通过构造器参数体现),
//否则,抛异常
Date date1 = sdf1.parse("2020-02-18 11:48:27");
System.out.println(date1);
- Calendar类:该类是日历类,也是一个抽象类。简单介绍一下用法:
//1.创建Calendar类的对象有两种方式:
//方式一:创建其子类(GregorianCalendar的对象)
//方式二:调用其静态方法getInstance()
Calendar calendar = Calendar.getInstance();
//2.常用方法
//get()
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//获取本月内的第几天,从1开始
System.out.println(calendar.get(Calendar.DAY_OF_YEAR));//获取一年内的第几天,从1开始
//set()
//calendar可变性
calendar.set(Calendar.DAY_OF_MONTH,22); // 设置日期为本月内的第22天
System.out.println(calendar.get(Calendar.DAY_OF_MONTH)); //输出22
//add()
calendar.add(Calendar.DAY_OF_MONTH,-3); // 设置日期为今天的日期-3天;
System.out.println(calendar.get(Calendar.DAY_OF_MONTH)); // 今天是11月8号,所以输出5
//getTime():日历类---> Date
Date date = calendar.getTime(); // 返回Date对象
System.out.println(date);//输出Sun Nov 08 17:49:57 CST 2020
//setTime():Date ---> 日历类
Date date = new Date();
calendar.setTime(date);
System.out.println(calendar.get(Calendar.YEAR)); // 输出2020
System.out.println(date.getYear()); // 输出120,此方法输出的是今年与1900年之差
Calendar类本意是为了弥补了Date类的缺陷而生的,但是随着在开发中的使用,渐渐的暴露出它们的不足。比如糟糕的可变性、偏移性等等。下面,我们一起来看看jdk1.8之后,关于日期的处理。
三、jdk1.8引入的关于时间处理的API
回顾Java对日期时间的迭代:
- 第一代:jdk 1.0 Date类
- 第二代:jdk 1.1 Calendar类,一定程度上替换Date类
- 第三代:jdk 1.8 提出了新的一套API
前两代存在的问题举例:
- 可变性:像日期和时间这样的类应该是不可变的。
- 偏移性:Date中的年份是从1900开始的,而月份都从0开始。
- 格式化:格式化只对Date用,Calendar则不行。
- 此外,它们也不是线程安全的;不能处理闰秒等。
java 8 中新的日期时间API涉及到的包:
1. 本地日期、本地时间、本地日期时间的使用:LocalDate / LocalTime / LocalDateTime
- 简介
① 分别表示使用 ISO-8601日历系统的日期、时间、日期时间。它们提供了简单的本地日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息。
② LocalDateTime相较于LocalDate、LocalTime,使用频率要高
③ 类似于Calendar
- 常用方法:
2. 时间点:Instant
- 简介
① 时间线上的一个瞬时点。概念上讲,它只是简单的表示自1970年1月1日0时0分0秒(UTC开始的秒数。)
② 类似于 java.util.Date类
- 常用方法:
3. 日期时间格式化类:DateTimeFormatter
- 简介
① 格式化或解析日期、时间
② 类似于SimpleDateFormat
- 实例化方式:
预定义的标准格式。如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
本地化相关的格式。如:ofLocalizedDateTime(FormatStyle.LONG)
自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
- 常用方法:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
//格式化
String str = formatter.format(LocalDateTime.now());
System.out.println(str);//2020-11-08 06:48:13
//解析
TemporalAccessor accessor = formatter.parse("2020-11-08 06:48:13");
System.out.println(accessor);
//输出{SecondOfMinute=13, MinuteOfHour=48, MicroOfSecond=0, MilliOfSecond=0, NanoOfSecond=0, HourOfAmPm=6},ISO resolved to 2020-11-08
4. 其他API
- 带时区的日期时间:ZonedDateTime / ZoneId
//获取“Asia/Tokyo”时区对应的时间
LocalDateTime localDateTime = LocalDateTime.now(ZoneId.of("Asia/Tokyo"));
System.out.println(localDateTime);//2020-11-08T19:57:38.479
//now()/now(ZoneId id):获取当前时区/指定时区的ZonedDateTime对象
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
System.out.println(zonedDateTime);//2020-11-08T19:58:45.084+09:00[Asia/Tokyo]
- 时间间隔:Duration—用于计算两个“时间”间隔,以秒和纳秒为基准
//设置起始日期时间,获取当前日期时间
LocalDateTime localDateTime = LocalDateTime.of(2016, 11, 8, 19, 2, 00);
LocalDateTime localDateTime1 = LocalDateTime.now();
Duration duration = Duration.between(localDateTime, localDateTime1);//返回间隔对象
System.out.println(duration.toDays()); //输出1461
- 日期间隔:Period —用于计算两个“日期”间隔,以年、月、日衡量
LocalDate localDate = LocalDate.now();
LocalDate localDate1 = LocalDate.of(2030, 11, 8);
Period period = Period.between(localDate, localDate1);
System.out.println(period); //P10Y
System.out.println(period.getYears()); // 10
System.out.println(period.getMonths()); // 0
System.out.println(period.getDays()); // 0
- 日期时间校正器:TemporalAdjuster
//获取当前日期的下一个周日是哪天?
TemporalAdjuster temporalAdjuster = TemporalAdjusters.next(DayOfWeek.SUNDAY);
LocalDateTime localDateTime = LocalDateTime.now().with(temporalAdjuster);
System.out.println(localDateTime); //2020-11-15T19:15:51.426
//获取下一个工作日是哪天?今天是2020-11-08
LocalDate localDate = LocalDate.now().with(new TemporalAdjuster(){
@Overridepublic Temporal adjustInto(Temporal temporal) {
LocalDate date = (LocalDate)temporal;
if(date.getDayOfWeek().equals(DayOfWeek.FRIDAY)){
return date.plusDays(3);//如果是周五,则+3
}else if(date.getDayOfWeek().equals(DayOfWeek.SATURDAY)){
return date.plusDays(2);//如果是周六,则+2
}else{
return date.plusDays(1);//其他情况,则+1
}
}
});
System.out.println("下一个工作日是:" + localDate); //下一个工作日是:2020-1