java的时间api一直是一个诟病,包括util和sql包下的Date类,以及text包下的Format类,以及Canlendar类。感觉乱七八糟,用起来总感觉不那么舒服。java8更新了新的时间API,在java.time包下,统一了时间api的用法,也很方便。下面我们简单了解一下新时间API的常用类和方法。
Clock
Clock时钟类,可以用此类来获取当前的毫秒数,使用millis方法。需要注意的是,Clock是像正常的时钟一样是时刻在变动的,也就是说不同时刻调用millis方法,返回的都是调用时刻的毫秒数,相当于调用的System.currentTimeMillis方法。所以可以用millis方法来替换currentTimeMillis的用法。如下所示:
Clock clock = Clock.systemDefaultZone();
System.out.println(clock.millis());
Thread.sleep(1000);
System.out.println(clock.millis());
输出结果如下:
1506313085859
1506313086860
Instant
Instant表示特定的某个时刻,一经创建就确定下来了,不会再改变。通过调用toEpochMilli方法,也可以获得毫秒数。可以通过Clock类来获得一个当前的时刻,或者通过一个固定的毫秒数来获得一个特定时刻。实例如下:
Clock clock = Clock.systemDefaultZone();
//当前时刻Instant
Instant instant = Instant.now();
System.out.println(instant.toEpochMilli());
Thread.sleep(1000);//不会影响输出结果
System.out.println(instant.toEpochMilli());
//通过时钟创建当前时刻,虽然时钟对象是在之前创建,但它创建的Instant也是当前时刻
instant = clock.instant();
System.out.println(instant.toEpochMilli());
//使用毫秒数构建Instant
instant = Instant.ofEpochMilli(1506310760160L);
System.out.println(instant.toEpochMilli());
输出结果如下:
1506319591032
1506319591032
1506319592032
1506310760160
LocalDate
表示一个日期,通常格式为year-month-day。通过此类我们可以获得一些和当天有关的日期属性,比如:day-of-year,day-of-week and week-of-year等。比如我们知道某人的生日为1988年07月06日,我们要获得一下出生那天是星期几,是一年中的第几个星期等信息,实例如下:
//当前日期
LocalDate today = LocalDate.now();
System.out.println(today);
//格式化
System.out.println(today.format(DateTimeFormatter.ofPattern("yyyyMMdd")));
//由生日获得对象
LocalDate birthday = LocalDate.parse("1988-07-06");
System.out.println(birthday);
//常用方法
System.out.println("年份:"+birthday.getYear());
System.out.println("月份:"+birthday.getMonthValue());
System.out.println("日份:"+birthday.getDayOfMonth());
System.out.println("一年中第几天:"+birthday.getDayOfYear());
System.out.println("星期:"+birthday.getDayOfWeek());
System.out.println("月份天数:"+birthday.lengthOfMonth());
System.out.println("年份天数:"+birthday.lengthOfYear());
System.out.println("是否闰年:"+birthday.isLeapYear());
//日期比较
System.out.println(today.isBefore(birthday));
System.out.println(today.isAfter(birthday));
System.out.println(today.isEqual(birthday));
输出结果如下:
2017-09-25
20170925
1988-07-06
年份:1988
月份:7
日份:6
一年中第几天:188
星期:WEDNESDAY
月份天数:31
年份天数:366
是否闰年:true
false
true
false
LocalTime
表示一个时间,通常格式为:hour-minute-second.可以获得当前时分秒等属性。实例如下:
//当前时间
LocalTime now = LocalTime.now();
System.out.println(now);
//格式化
System.out.println(now.format(DateTimeFormatter.ofPattern("HH:mm:ss")));
//常用方法
System.out.println("时:"+now.getHour());
System.out.println("分:"+now.getMinute());
System.out.println("秒:"+now.getSecond());
System.out.println("纳秒:"+now.getNano());
System.out.println("当天所经过的秒数:"+now.toSecondOfDay());
System.out.println("当天所经过的纳秒数:"+now.toNanoOfDay());
//时间比较
LocalTime time = LocalTime.parse("05:01:01");
System.out.println(time.isAfter(now));
System.out.println(time.isBefore(now));
输出结果如下:
15:20:00.518
15:20:00
时:15
分:20
秒:0
纳秒:518000000
当天所经过的秒数:55200
当天所经过的纳秒数:55200518000000
false
true
LocalDateTime
LocalDateTime是LocalDate和LocalTime的整合体,表示日期和时间。通常格式为:year-month-day-hour-minute-second。包含了LocalDate和LocalTime的常用方法,并且可以相互转换。实例代码如下:
//当前时间
LocalDateTime dateTime = LocalDateTime.now();
System.out.println(dateTime);
//格式化
System.out.println(dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
//LocalDate转化为LocalDateTime
LocalDate date = LocalDate.now();
LocalDateTime startOfDay = date.atStartOfDay();
System.out.println("start of day:"+startOfDay);
LocalDateTime atTime = date.atTime(LocalTime.parse("04:03:39"));
System.out.println("localDate at time:"+atTime);
//LocalTime转化为LocalDateTime
LocalTime time = LocalTime.parse("04:03:39");
LocalDateTime atDate = time.atDate(date);
System.out.println("localTime at date:"+atDate);
//LocalDateTime转化为LoalDate和LocalTime
System.out.println("localDateTime toLocalDate:"+dateTime.toLocalDate());
System.out.println("localDateTime toLocalTime:"+dateTime.toLocalTime());
//LocalDateTime的常用方法
System.out.println("年份:"+dateTime.getYear());
System.out.println("月份:"+dateTime.getMonthValue());
System.out.println("日份:"+dateTime.getDayOfMonth());
System.out.println("一年中第几天:"+dateTime.getDayOfYear());
System.out.println("星期:"+dateTime.getDayOfWeek());
System.out.println("时:"+dateTime.getHour());
System.out.println("分:"+dateTime.getMinute());
System.out.println("秒:"+dateTime.getSecond());
System.out.println("纳秒:"+dateTime.getNano());
Duration
Duration用来表示两个日期之间的间隔(单位分钟)。可计算LocalDateTime,LocalTime和Instant表示的时间之间的间隔。值得注意的LocalDate不在其行列,因为LocalDate并没有精确到分钟,所以没有办法计算。实例代码如下:
//LocalDateTime
DateTimeFormatter ofPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime datetime1 = LocalDateTime.parse("2017-01-01 08:12:02",ofPattern);
LocalDateTime datetime2 = LocalDateTime.parse("2017-02-01 08:12:02",ofPattern);
Duration between = Duration.between(datetime1, datetime2);
System.out.println("间隔分钟:"+between.getSeconds());
//LocalTime
DateTimeFormatter ofPattern1 = DateTimeFormatter.ofPattern("HH:mm:ss");
LocalTime time1 = LocalTime.parse("08:12:02",ofPattern1);
LocalTime time2 = LocalTime.parse("08:15:02",ofPattern1);
between = Duration.between(time1, time2);
System.out.println("间隔分钟:"+between.getSeconds());
//Instant
Instant instant2 = Instant.now();
Instant instant1 = Instant.ofEpochMilli(1506225869099L);
between = Duration.between(instant1, instant2);
System.out.println("间隔分钟:"+between.getSeconds());
输出结果如下:
间隔分钟:2678400
间隔分钟:180
间隔分钟:100295
日期运算
各个日期类都可以通过plus和minus函数进行加减操作,代码如下所示:
LocalDate date = LocalDate.now();
System.out.println("现在日期:"+date);
System.out.println("加1天:"+date.plusDays(1));
System.out.println("加2月星期:"+date.plusMonths(2));
System.out.println("加23:"+date.plusWeeks(23));
System.out.println("加2年:"+date.plusYears(2));
System.out.println("减1天:"+date.minusDays(1));
System.out.println("减2月星期:"+date.minusMonths(2));
System.out.println("减23:"+date.minusWeeks(23));
System.out.println("减2年:"+date.minusYears(2));
LocalTime now = LocalTime.now();
System.out.println("现在时间:"+now);
System.out.println("加1小时:"+now.plusHours(1));
System.out.println("加10分钟:"+now.plusMinutes(10));
System.out.println("减1小时:"+now.minusHours(1));
System.out.println("减10分钟:"+now.minusMinutes(10));
LocalDateTime dateTime = LocalDateTime.now();
System.out.println("现在日期:"+dateTime);
System.out.println("加1天:"+dateTime.plusDays(1));
System.out.println("加2月星期:"+dateTime.plusMonths(2));
System.out.println("加23:"+dateTime.plusWeeks(23));
System.out.println("加2年:"+dateTime.plusYears(2));
System.out.println("减1天:"+dateTime.minusDays(1));
System.out.println("减2月星期:"+dateTime.minusMonths(2));
System.out.println("减23:"+dateTime.minusWeeks(23));
System.out.println("减2年:"+dateTime.minusYears(2));
System.out.println("加1小时:"+dateTime.plusHours(1));
System.out.println("加10分钟:"+dateTime.plusMinutes(10));
System.out.println("减1小时:"+dateTime.minusHours(1));
System.out.println("减10分钟:"+dateTime.minusMinutes(10));
Instant instant = Instant.now();
System.out.println("现在日期:"+instant);
System.out.println("加10万毫秒"+instant.plusMillis(100000));
输出结果如下:
现在日期:2017-09-25
加1天:2017-09-26
加2月星期:2017-11-25
加23:2018-03-05
加2年:2019-09-25
减1天:2017-09-24
减2月星期:2017-07-25
减23:2017-04-17
减2年:2015-09-25
现在时间:16:05:10.295
加1小时:17:05:10.295
加10分钟:16:15:10.295
减1小时:15:05:10.295
减10分钟:15:55:10.295
现在日期:2017-09-25T16:05:10.295
加1天:2017-09-26T16:05:10.295
加2月星期:2017-11-25T16:05:10.295
加23:2018-03-05T16:05:10.295
加2年:2019-09-25T16:05:10.295
减1天:2017-09-24T16:05:10.295
减2月星期:2017-07-25T16:05:10.295
减23:2017-04-17T16:05:10.295
减2年:2015-09-25T16:05:10.295
加1小时:2017-09-25T17:05:10.295
加10分钟:2017-09-25T16:15:10.295
减1小时:2017-09-25T15:05:10.295
减10分钟:2017-09-25T15:55:10.295
现在日期:2017-09-25T08:05:10.297Z
加10万毫秒2017-09-25T08:06:50.297Z
格式转换
对象和字符串以及毫秒之间的相互转化,代码如下所示:
//对象转字符串
LocalDate date = LocalDate.now();
String format = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
System.out.println(format);
format = date.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
System.out.println(format);
LocalTime time = LocalTime.now();
format = time.format(DateTimeFormatter.ofPattern("HH:mm:ss"));
System.out.println(format);
format = time.format(DateTimeFormatter.ofPattern("HH-mm-ss"));
System.out.println(format);
LocalDateTime dateTime = LocalDateTime.now();
format = dateTime.format(DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss"));
System.out.println(format);
format = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH-mm-ss"));
System.out.println(format);
//字符串转对象
date = LocalDate.parse("2017-01-01",DateTimeFormatter.ofPattern("yyyy-MM-dd"));
System.out.println(date);
time = LocalTime.parse("01-01-01", DateTimeFormatter.ofPattern("HH-mm-ss"));
System.out.println(time);
dateTime = LocalDateTime.parse("2017-01-01 01:01:01", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(dateTime);
//Instant 转化为毫秒
Instant instant = Instant.now();
System.out.println(instant.toEpochMilli());
//毫秒 转化为 Instant
System.out.println(Instant.ofEpochMilli(1506327309181L));
//LocalDateTime转化为毫秒
long millis = dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
System.out.println(millis);
//毫秒转化为LocalDateTime
dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(1506327309181L), ZoneId.systemDefault());
System.out.println(dateTime);
输出结果如下:
2017-09-25
20170925
16:17:22
16-17-22
20170925 16:17:22
2017-09-25 16-17-22
2017-01-01
01:01:01
2017-01-01T01:01:01
1506327442411
2017-09-25T08:15:09.181Z
1483203661000
2017-09-25T16:15:09.181
工具类
使用新的API写的日期工具类,比较简单,抛砖引玉,各位大拿可自行添加工具方法。
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
/**
* java 1.8时间api
*
* @author chuer
* @date 2017年9月22日 上午11:19:03
*/
public class TimeUtil {
public static final DateTimeFormatter YYYY_MM_DD_HH_MM_SS = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public static final DateTimeFormatter YYYY_MM_DD = DateTimeFormatter.ofPattern("yyyy-MM-dd");
public static final DateTimeFormatter HH_MM_SS = DateTimeFormatter.ofPattern("HH:mm:ss");
/**
* @return 返回格式yyyy-MM-dd
*/
public static String date() {
return LocalDate.now().format(YYYY_MM_DD);
}
/**
* @return 返回当前年份
*/
public static int year() {
return LocalDate.now().getYear();
}
/**
* @return 返回当前月份
*/
public static int month() {
return LocalDate.now().getMonthValue();
}
/**
* @return 返回今日是月份中的第几天
*/
public static int dayOfMonth() {
return LocalDate.now().getDayOfMonth();
}
/**
* @return 返回今日是一年中的第几天
*/
public static int dayOfYear() {
return LocalDate.now().getDayOfYear();
}
/**
* @return 返回今日星期几 1-7
*/
public static int dayOfWeek() {
return LocalDate.now().getDayOfWeek().getValue();
}
/**
* @param year
* @param month
* @param day
* @return 返回指定日期
*/
public static String newDate(int year, int month, int day) {
return LocalDate.of(year, month, day).toString();
}
/**
* @param year
* 指定年份
* @param day
* 指定年份中的天数
* @return 根据条件返回日期
*/
public static String newDate(int year, int dayNum) {
return LocalDate.ofYearDay(year, dayNum).toString();
}
/**
* @return 返回当前时间 HH:mm:ss.xxx
*/
public static String time() {
return LocalTime.now().format(HH_MM_SS);
}
/**
* @return 当前小时
*/
public static int hour() {
return LocalTime.now().getHour();
}
/**
* @return 当前分钟
*/
public static int minute() {
return LocalTime.now().getMinute();
}
/**
* @return 当前秒
*/
public static int second() {
return LocalTime.now().getSecond();
}
/**
* @return 返回格式 yyyy-MM-dd HH:mm:ss
*/
public static String dateTime() {
return LocalDateTime.now().format(YYYY_MM_DD_HH_MM_SS);
}
/**
* @param time
* 从1970-01-01T00:00:00到现在的毫秒数
*/
public static LocalDateTime parseDateTime(long time) {
return LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault());
}
/**
* @param time
* yyyy-MM-dd HH:mm:ss
*/
public static LocalDateTime parseDateTime(String time) {
return LocalDateTime.parse(time, YYYY_MM_DD_HH_MM_SS);
}
/**
* @param time
* 从1970-01-01T00:00:00到现在的毫秒数
* @return
*/
public static LocalDate parseDate(long time) {
return LocalDate.from(parseDateTime(time));
}
/**
* @param time
* yyyy-MM-dd
* @return
*/
public static LocalDate parseDate(String time) {
return LocalDate.parse(time, YYYY_MM_DD);
}
/**
* yyyy-MM-dd
*
* @param date
* @return
*/
public static String format(LocalDate date) {
return date.format(YYYY_MM_DD);
}
/**
* @param dateTime
* @return
*/
public static String format(LocalDateTime dateTime) {
return dateTime.format(YYYY_MM_DD_HH_MM_SS);
}
/**
* 转化为毫秒,默认为
* @param date
* @return
*/
public static long millis(LocalDate date) {
return millis(date.atStartOfDay());
}
/**
* 转化为毫秒
* @param dateTime
* @return
*/
public static long millis(LocalDateTime dateTime) {
return dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
}