java8 重新定义了一套语义非常清晰的日期、时间Api,位于java.time包中。该包中的所有类都是不可变且线程安全的。
在java8中,java.time包下主要包含下面几个主要的类:
Instant:时间戳
Duration:持续时间,时间差
LocalDate:只包含日期,比如:2016-10-20
LocalTime:只包含时间,比如:23:12:10
LocalDateTime:包含日期和时间,比如:2016-10-20 23:14:21
Period:时间段
ZoneOffset:时区偏移量,比如:+8:00
ZonedDateTime:带时区的时间
Clock:时钟,比如获取目前美国纽约的时间
以及java.time.format包中的
DateTimeFormatter:时间格式化
用法
时间操作
now(),创建当前时间,可指定时区
//当前本地时间:2018-12-16T13:45:11.232
LocalDateTime localDateTime = LocalDateTime.now();
//当前美国洛杉矶时间:2018-12-15T21:45:11.251
LocalDateTime losAngelesTime = LocalDateTime.now(ZoneId.of("America/Los_Angeles"));
LocalDateTime losAngelesTime2 = LocalDateTime.now(Clock.system(ZoneId.of("America/Los_Angeles")));
of(),创建指定的时间
// 2019-01-01T12:00:01 注:月份是从1开始算的了,不想Calendar是从0开始的
LocalDateTime time = LocalDateTime.of(2019, 1, 1, 12, 0, 1);
//另外月份也可以使用Month枚举类
LocalDateTime time1 = LocalDateTime.of(2019, Month.AUGUST, 1, 12, 1, 1);
getXXX(),获取某个时间字段
LocalDateTime now = LocalDateTime.now();
//获取年份 2018
int year = now.getYear();
//获取周几 7(星期天)
int dayOfWeek = now.getDayOfWeek().getValue();
//获取小时 14
int hour = now.getHour();
withXXX(),跳到指定的时间
//2018-12-16T14:12:32.162
LocalDateTime now = LocalDateTime.now();
//2019-02-16T14:10:32.162
LocalDateTime withTime = now.withYear(2019).withMonth(2).withMinute(10);
plusXXX() / minusXXX() ,加 / 减 某个时间
//2018-12-16T14:18:01.005
LocalDateTime now = LocalDateTime.now();
//2019-01-01T14:18:01.005
LocalDateTime plusTime = now.plusDays(16);
//2018-12-16T04:18:01.005
LocalDateTime minusTime = now.minusHours(10);
parse() / format(),解析时间 /格式化时间
//ofPattern 是自定义自己的格式
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String timeStr="2018-12-31 23:59:59";
LocalDateTime parseTime = LocalDateTime.parse(timeStr, dateTimeFormatter);
//DateTimeFormatter也提供一些自带的格式
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
LocalDateTime now = LocalDateTime.now();
String formatTime = now.format(formatter); //2018年12月16日 星期日
Duration 或 Period
都是表示一段时间长度(时间量),只是Duration偏向“时间”方面的,如 10秒,1小时。而Period则偏向于“日期”方面的,如 1个月,1年。
//Duration 可以获取到两个时间相差的天数、小时、分钟、秒、毫秒
LocalDateTime ldt1 = LocalDateTime.of(2018, 10, 10, 12, 10, 10);
LocalDateTime ldt2 = LocalDateTime.of(2019, 5, 2, 2, 10, 10);
Duration duration = Duration.between(ldt1, ldt2);
System.out.println(duration.getSeconds()); // 17589600
System.out.println(duration.toHours()); // 4886
System.out.println(duration.toDays()); // 203
//Period 可以获取到两个时间相差的年数和月数
LocalDate ld1 = LocalDate.of(2017, 12, 26);
LocalDate ld2 = LocalDate.of(2019, 3, 27);
Period period = Period.between(ld1,ld2);
System.out.println(period.getYears()); // 1
System.out.println(period.toTotalMonths()); // 15
//特别注意以下两个getXXX()
System.out.println(period.getDays()); // 1
System.out.println(period.getMonths()); // 3
LocalDateTime 与 Date 互转
/**
* 将localDateTime 转为 date
*/
public static Date localDateTime2Date(LocalDateTime localDateTime) {
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
Instant instant = zonedDateTime.toInstant();
return Date.from(instant);
}
/**
* 将date转为LocalDatetTime
*/
public static LocalDateTime date2LocalDateTime(Date date) {
Instant instant = date.toInstant();
ZoneId zoneId = ZoneId.systemDefault();
return instant.atZone(zoneId).toLocalDateTime();
}
常见日期操作
检查生日:MonthDay 类。这个类组合了月份和日,去掉了年,这意味着你可以用它判断每年都会发生事件。和这个类相似的还有一个 YearMonth 类。
LocalDate now = LocalDate.now();
LocalDate dateOfBirth = LocalDate.of(2018, 06, 20);
MonthDay birthday = MonthDay.of(dateOfBirth.getMonth(), dateOfBirth.getDayOfMonth());
MonthDay currentMonthDay = MonthDay.from(now);
if (currentMonthDay.equals(birthday)) {
System.out.println("Happy Birthday");
} else {
System.out.println("Sorry, today is not your birthday");
}
计算一周后的日期:LocalDate 日期不包含时间信息,它的 plus()方法用来增加天、周、月,ChronoUnit 类声明了这些时间单位。
LocalDate now = LocalDate.now();
LocalDate plusDate = now.plus(1, ChronoUnit.WEEKS);
System.out.println(now);
System.out.println(plusDate);
检查闰年:LocalDate 类有一个很实用的方法 isLeapYear() 判断该实例是否是一个闰年。
LocalDate today = LocalDate.now();
System.out.println("今年是否是闰年:"+today.isLeapYear());