之前有谈过Java的两套时间工具,分别是Date日期类型和Calendar日历类型,但仍在开发中存在问题:
为解决以上问题,Java 8 提供了全新的本地日期时间类型,它的成员主要有LocalDate、LocalTime、LocalDateTime等。
import java.time.LocalDate;
获得本地日期实例很简单,就直接调用该类型的now方法,顾名思议就是获得当前日期,很符合我们常理,且还额外提供了几个常用的统计方法。
注意:
import java.time.Month;
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特此提供了专门的增减改方法。
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);
前面介绍的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所有的。
现在有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这三个方法。
之前介绍了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);