Java 8 的日期时间工具

之前有谈过Java的两套时间工具,分别是Date日期类型和Calendar日历类型,但仍在开发中存在问题:

  • 日历工具获得当月份的时候,与Date一样都是从0开始计数,比如通过get方法获得一月份数值为0;
  • 日历工具获得当天是星期几的时候,星期日是排在最前面的,通过get方法获得的星期日数值为1,而星期一数值居然为2;
  • 日历工具能够表达的最小世界单位是毫秒,精度不高;
  • 日历工具没有提供闰年判断方法;
  • 日历工具缺乏自己的格式,还得借助Date类型的格式化工具SimpleDateFormat,才能将日期时间按照指定格式输出为字符串。

为解决以上问题,Java 8 提供了全新的本地日期时间类型,它的成员主要有LocalDate、LocalTime、LocalDateTime等。

1. LocalDate 和 LocalTime

1.1 本地日期类型LocalDate

import java.time.LocalDate;

获得本地日期实例很简单,就直接调用该类型的now方法,顾名思议就是获得当前日期,很符合我们常理,且还额外提供了几个常用的统计方法。

注意:

  • getMonth() 返回的是英文月份,而 getMonthValue() 返回的是数字月份!

import java.time.Month;

  • getDayOfWeek() 返回的是英文星期,而后面加了getValue() 才返回数字星期几!

import java.time.DayOfWeek;

【代码】

	// LocalDate的各种方法
		LocalDate date = LocalDate.now();// 获得本地日期的实例
		System.out.println("date:" + date.toString());
		int year = date.getYear(); // 获得该日期所在的年份
		System.out.println("year:" + year);
		
		//注意区分getMonth()返回的是英文月份,而getMonthValue()返回的是数字月份!
		int month1 = date.getMonthValue();
		Month month2 = date.getMonth();
		System.out.println("month:" + month1 + '\t' + month2);
		int dayOfYear = date.getDayOfYear();
		System.out.println("day:" + dayOfYear);
		
		//注意区分getDayOfWeek()返回的是英文星期,而后面加了getValue()才返回数字星期几!
		int dayOfWeek1 = date.getDayOfWeek().getValue();
		DayOfWeek dayOfWeek2 = date.getDayOfWeek();
		System.out.println("week:" + dayOfWeek1 + '\t' + dayOfWeek2);
		int lengthOfYear = date.lengthOfYear();
		System.out.println("lengthOfYear:" + lengthOfYear);
		int lengthOfMonth = date.lengthOfMonth();
		System.out.println("lengthOfMonth:" + lengthOfMonth);
		boolean isLeapYear = date.isLeapYear();// 判断该日期所在的年份是否为闰年
		System.out.println("isLeapYear:" + isLeapYear);

private static void showLocalDate() {
     
		LocalDate date = LocalDate.now(); // 获得本地日期的实例
		System.out.println("date=" + date.toString());
		int year = date.getYear(); // 获得该日期所在的年份
		System.out.println("year=" + year);
		// 获得该日期所在的月份。注意getMonthValue返回的是数字月份,getMonth返回的是英文月份
		int month = date.getMonthValue();
		System.out.println("month=" + month + ", english month=" + date.getMonth());
		int dayOfMonth = date.getDayOfMonth(); // 获得该日期所在的日子
		System.out.println("dayOfMonth=" + dayOfMonth);
		int dayOfYear = date.getDayOfYear(); // 获得该日期在一年当中的序号
		System.out.println("dayOfYear=" + dayOfYear);
		// 获得该日期是星期几。注意getDayOfWeek返回的是英文,后面的getValue才返回数字星期几
		int dayOfWeek = date.getDayOfWeek().getValue();
		System.out.println("dayOfWeek=" + dayOfWeek + ", english weekday=" + date.getDayOfWeek());
		int lengthOfYear = date.lengthOfYear(); // 获得该日期所在的年份一共有多少天
		System.out.println("lengthOfYear=" + lengthOfYear);
		int lengthOfMonth = date.lengthOfMonth(); // 获得该日期所在的月份一共有多少天
		System.out.println("lengthOfMonth=" + lengthOfMonth);
		boolean isLeapYear = date.isLeapYear(); // 判断该日期所在的年份是否为闰年
		System.out.println("isLeapYear=" + isLeapYear);
		

你们是否曾想过上面的LocalDate是访问当前本地实例,那是否支持访问自己指定日期的本地实例呢?答案肯定是支持的!使用…of()。
【cope】

		LocalDate dateManual = LocalDate.of(2019,12,17); // 构建一个指定日期实例
		System.out.println("dateManual=" + dateManual.toString());

那我想只改变日期的单位数值,而不至于大幅度改动,那怎么办呢?
LocalDate特此提供了专门的增减改方法。

  • plus开头方法:用于增加日期数值;
  • minus开头方法:用来减少日期数值;
  • with开头方法:用来设置日期数值。
		dateManual = dateManual.plusYears(0); // 增加若干年份
		dateManual = dateManual.plusMonths(0); // 增加若干月份
		dateManual = dateManual.plusDays(0); // 增加若干日子
		dateManual = dateManual.plusWeeks(0); // 增加若干星期
		dateManual = dateManual.minusYears(0); // 减少若干年份
		dateManual = dateManual.minusMonths(0); // 减少若干月份
		dateManual = dateManual.minusDays(0); // 减少若干日子
		dateManual = dateManual.minusWeeks(0); // 减少若干星期
		dateManual = dateManual.withYear(2000); // 设置指定的年份
		dateManual = dateManual.withMonth(12); // 设置指定的月份
		dateManual = dateManual.withDayOfYear(1); // 设置当年的日子
		dateManual = dateManual.withDayOfMonth(1); // 设置当月的日子

此外,作为一种日期类型,LocalDate一如既往地支持判断两个日期实例的早晚关系 equals、isBefore、isAfter等方法:

		boolean equalsDate = date.equals(dateManual); // 判断两个日期是否相等
		System.out.println("equalsDate=" + equalsDate);
		boolean isBeforeDate = date.isBefore(dateManual); // 判断A日期是否在B日期之前
		System.out.println("isBeforeDate=" + isBeforeDate);
		boolean isAfterDate = date.isAfter(dateManual); // 判断A日期是否在B日期之后
		System.out.println("isAfterDate=" + isAfterDate);
		boolean isEqualDate = date.isEqual(dateManual); // 判断A日期是否与B日期相等
		System.out.println("isEqualDate=" + isEqualDate);

1.2 本地时间类型LocalTime

前面介绍的LocateDate只能操作年月日,而不能操作时分秒,届时需通过LocalTime来操作,依然要调用该类型的now方法。

【代码】

		LocalTime time = LocalTime.now(); // 获得本地时间的实例
		System.out.println("time=" + time.toString());
		int hour = time.getHour(); // 获得该时间所在的时钟
		System.out.println("hour=" + hour);
		int minute = time.getMinute(); // 获得该时间所在的分钟
		System.out.println("minute=" + minute);
		int second = time.getSecond(); // 获得该时间所在的秒钟
		System.out.println("second=" + second);
		// 一秒等于一千毫秒,一毫秒等于一千微秒,一微秒等于一千纳秒,算下来一秒等于十亿纳秒
		int nano = time.getNano(); // 获得该时间秒钟后面的纳秒单位
		System.out.println("nano=" + nano);

还支持自己创建实例time;

		LocalTime timeManual = LocalTime.of(14, 30, 25); // 构造一个指定时分秒的时间实例
		System.out.println("timeManual=" + timeManual.toString());

也支持LocalDate的增减改方法:

		timeManual = timeManual.plusHours(0); // 增加若干时钟
		timeManual = timeManual.plusMinutes(0); // 增加若干分钟
		timeManual = timeManual.plusSeconds(0); // 增加若干秒钟
		timeManual = timeManual.plusNanos(0); // 增加若干纳秒
		timeManual = timeManual.minusHours(0); // 减少若干时钟
		timeManual = timeManual.minusMinutes(0); // 减少若干分钟
		timeManual = timeManual.minusSeconds(0); // 减少若干秒钟
		timeManual = timeManual.minusNanos(0); // 减少若干纳秒
		timeManual = timeManual.withHour(0); // 设置指定的时钟
		timeManual = timeManual.withMinute(0); // 设置指定的分钟
		timeManual = timeManual.withSecond(0); // 设置指定的秒钟
		timeManual = timeManual.withNano(0); // 设置指定的纳秒

也会提供比较两个时间的关系。

		boolean equalsTime = time.equals(timeManual); // 判断两个时间是否相等
		System.out.println("equalsTime=" + equalsTime);
		boolean isBeforeTime = time.isBefore(timeManual); // 判断A时间是否在B时间之前
		System.out.println("isBeforeTime=" + isBeforeTime);
		boolean isAfterTime = time.isAfter(timeManual); // 判断A时间是否在B时间之后
		System.out.println("isAfterTime=" + isAfterTime);

【小结】以上所用到的方法都是LocalDate所有的。

1.3 本地日期类型LocalDateTime

现在有LocalDate专门处理年月日,又有LocalTime专门处理时分秒,那有这部分提供他们俩的合集,即LocalDateTime,它同时拥有二者绝大部分方法,直接见代码:

而需注意的是LocalTime不提供lengthOfYear、lengthOfMonth、isLeapYear这三个方法。

		// 获得本地日期时间的实例
		LocalDateTime datetime = LocalDateTime.now();
		System.out.println("datetime=" + datetime.toString());
		// LocalDateTime的方法是LocalDate与LocalTime的合集,
		// 也就是说LocalDate与LocalTime的大部分方法可以直接拿来给LocalDateTime使用,
		// 因而下面不再演示LocalDateTime的详细方法如何调用了。
		// 注意LocalDateTime不提供lengthOfYear、lengthOfMonth、isLeapYear这三个方法。

2. 本地日期时间与字符串的互相转换

之前介绍了Date类型通过格式化工具SimpleDateFormat获得字符串,Java8也有专门本地日期时间的格式化工具DateTimeFormatter ,并定义几种常见的日期时间格式。

 import java.time.format.DateTimeFormatter;
DateTimeFormatter类的格式类型 对应的日期时间格式
BASIC_ISO_DATE yyyyMMdd
ISO_LOCAL_DATE yyyy-MM-dd
ISO_LOCAL_TIME HH:mm:ss
ISO_LOCAL_DATE_TIME yyyy-MM-ddTHH:mm:ss

现在只要调用本地日期时间的parse方法,即可将字符串形式转换为日期时间,无须像Calendar那样还得借助Date。

【代码】

		String strDateSimple = "20190729";
		// 把日期字符串转换为LocalDate实例。BASIC_ISO_DATE定义的日期格式为yyyyMMdd
		LocalDate dateSimple = LocalDate.parse(strDateSimple, DateTimeFormatter.BASIC_ISO_DATE);
		System.out.println("dateSimple=" + dateSimple.toString());
		String strDateWithLine = "2019-07-29";
		// 把日期字符串转换为LocalDate实例。ISO_LOCAL_DATE定义的日期格式为yyyy-MM-dd
		LocalDate dateWithLine = LocalDate.parse(strDateWithLine, DateTimeFormatter.ISO_LOCAL_DATE);
		System.out.println("dateWithLine=" + dateWithLine.toString());
		String strTimeWithColon = "12:44:50";
		// 把时间字符串转换为LocalTime实例。ISO_LOCAL_TIME定义的时间格式为HH:mm:ss
		LocalTime timeWithColon = LocalTime.parse(strTimeWithColon, DateTimeFormatter.ISO_LOCAL_TIME);
		System.out.println("timeWithColon=" + timeWithColon.toString());
		String strDateTimeISO = "2019-11-23T14:46:30";
		// 把日期时间字符串转换为LocalDateTime实例。ISO_LOCAL_DATE_TIME定义的日期时间格式为yyyy-MM-ddTHH:mm:ss
		LocalDateTime datetimeISO = LocalDateTime.parse(strDateTimeISO, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
		System.out.println("datetimeISO=" + datetimeISO.toString());

除了系统自带的几种日期时间格式外,我们可以自己定义其他格式,此时需要调用DateTimeFormatter的ofPattern方法完成格式化定义,使用ofPattern方法得到某个格式化实例,就能直接代入本地日期时间的parse方法中。

【代码】

		String strDateWithSway = "2019/07/29";
		// 自己定义了一个形如“yyyy/MM/dd”的日期格式
		DateTimeFormatter dateFormatWithSway = DateTimeFormatter.ofPattern("yyyy/MM/dd");
		// 把日期字符串按照格式“yyyy/MM/dd”转换为LocalDate实例
		LocalDate dateWithSway = LocalDate.parse(strDateWithSway, dateFormatWithSway);
		System.out.println("dateWithSway=" + dateWithSway.toString());
		String strTimeSimple = "125809";
		// 自己定义了一个形如“HHmmss”的时间格式
		DateTimeFormatter timeFormatSimple = DateTimeFormatter.ofPattern("HHmmss");
		// 把时间字符串按照格式“HHmmss”转换为LocalTime实例
		LocalTime timeSimple = LocalTime.parse(strTimeSimple, timeFormatSimple);
		System.out.println("timeSimple=" + timeSimple.toString());
		String strWithCn = "2019年07月29日12时58分09秒";
		// 自己定义了一个形如“yyyy年MM月dd日HH时mm分ss秒”的日期时间格式
		DateTimeFormatter formatCn = DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时mm分ss秒");
		// 把日期时间字符串按照格式“yyyy年MM月dd日HH时mm分ss秒”转换为LocalDateTime实例
		LocalDateTime datetimeWithCn = LocalDateTime.parse(strWithCn, formatCn);
		System.out.println("datetimeWithCn=" + datetimeWithCn.toString());

既然字符串能通过parse方法转化成为本地日期时间,反过来可以采用format方法将本地日期时间转化成为字符串类型。

【代码】

		LocalDate date = LocalDate.now(); // 获得当前日期的实例
		// 把LocalDate实例转换为日期字符串。BASIC_ISO_DATE定义的日期格式为yyyyMMdd
		String strDateSimple = date.format(DateTimeFormatter.BASIC_ISO_DATE);
		System.out.println("strDateSimple=" + strDateSimple);
		// 把LocalDate实例转换为日期字符串。ISO_LOCAL_DATE定义的日期格式为yyyy-MM-dd
		String strDateWithLine = date.format(DateTimeFormatter.ISO_LOCAL_DATE);
		System.out.println("strDateWithLine=" + strDateWithLine);
		// 自己定义了一个形如“yyyy/MM/dd”的日期格式
		DateTimeFormatter dateFormatWithSway = DateTimeFormatter.ofPattern("yyyy/MM/dd");
		// 把LocalDate实例按照格式“yyyy/MM/dd”转换为日期字符串
		String strDateWithSway = date.format(dateFormatWithSway);
		System.out.println("strDateWithSway=" + strDateWithSway);
		LocalTime time = LocalTime.now(); // 获得当前时间的实例
		// 把LocalTime实例转换为时间字符串。ISO_LOCAL_TIME定义的时间格式为HH:mm:ss
		String strTimeWithColon = time.format(DateTimeFormatter.ISO_LOCAL_TIME);
		System.out.println("strTimeWithColon=" + strTimeWithColon);
		// 自己定义了一个形如“HHmmss”的时间格式
		DateTimeFormatter timeFormatSimple = DateTimeFormatter.ofPattern("HHmmss");
		// 把LocalTime实例按照格式“HHmmss”转换为时间字符串
		String strTimeSimple = time.format(timeFormatSimple);
		System.out.println("strTimeSimple=" + strTimeSimple);
		LocalDateTime datetime = LocalDateTime.now(); // 获得当前日期时间的实例
		// 自己定义了一个形如“yyyy年MM月dd日HH时mm分ss秒”的日期时间格式
		DateTimeFormatter formatCn = DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时mm分ss秒");
		// 把LocalDateTime实例按照格式“yyyy年MM月dd日HH时mm分ss秒”转换为日期时间字符串
		String strWithCn = datetime.format(formatCn);
		System.out.println("strWithCn=" + strWithCn);

你可能感兴趣的:(Java基础,日期时间,java)