一、获取系统当前时间

想获取系统当前时间,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类的子类。

DateTime java 没有 类型吗 java datetime类型的值_sql

搞清楚了两者之间的区别和联系后,我们来回答两个问题:

  • 第一个问题:如何将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

前两代存在的问题举例:

  1. 可变性:像日期和时间这样的类应该是不可变的。
  2. 偏移性:Date中的年份是从1900开始的,而月份都从0开始。
  3. 格式化:格式化只对Date用,Calendar则不行。
  4. 此外,它们也不是线程安全的;不能处理闰秒等。

java 8 中新的日期时间API涉及到的包:

DateTime java 没有 类型吗 java datetime类型的值_sql_02

1. 本地日期、本地时间、本地日期时间的使用:LocalDate / LocalTime / LocalDateTime

  • 简介

① 分别表示使用 ISO-8601日历系统的日期、时间、日期时间。它们提供了简单的本地日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息。
② LocalDateTime相较于LocalDate、LocalTime,使用频率要高
③ 类似于Calendar

  • 常用方法:

DateTime java 没有 类型吗 java datetime类型的值_sql_03

2. 时间点:Instant

  • 简介

① 时间线上的一个瞬时点。概念上讲,它只是简单的表示自1970年1月1日0时0分0秒(UTC开始的秒数。)
② 类似于 java.util.Date类

  • 常用方法:

DateTime java 没有 类型吗 java datetime类型的值_java_04

3. 日期时间格式化类:DateTimeFormatter

  • 简介

            ① 格式化或解析日期、时间
            ② 类似于SimpleDateFormat

  • 实例化方式:

预定义的标准格式。如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME

本地化相关的格式。如:ofLocalizedDateTime(FormatStyle.LONG)

自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)

  • 常用方法:

DateTime java 没有 类型吗 java datetime类型的值_java_05

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—用于计算两个“时间”间隔,以秒和纳秒为基准

DateTime java 没有 类型吗 java datetime类型的值_java date类型_06

//设置起始日期时间,获取当前日期时间
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 —用于计算两个“日期”间隔,以年、月、日衡量

DateTime java 没有 类型吗 java datetime类型的值_java_07

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