Java 8 中的日期API相比以前更为简洁,辨识度高,而且都是线程安全的。掌握常用的时间类方法有时可以节省许多额外的工作。关于各个类的介绍可以参考Java 8新特性(四):新的时间和日期API
值得注意的是,LocalTime 、LocalDate 与 LocalDateTime 类的构造器都是 private,这里用了静态工厂方法(static factory methods)。静态工厂方法相比传统的构造器有如下优点(参考Effective Java第二版):
- 静态工厂方法在方法命名上更具有可读性
- 静态工厂方法可以在被调用的时候返回同一个对象,而不是每次都构建一个新的对象
- 静态工厂方法可以返回该类型的子类对象
- 静态工厂方法可以简化参数化类型的对象创建
关于第四点,Java 7 已经开始支持泛型类型推导,并在Java 8 中得到了完善(Java8中对泛型目标类型推断方法的改进)。
下面是应用新的API写的一些例子,基本能够满足日常需要。
- 获取当前日期时间
LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime dateTime = LocalDateTime.now().withNano(0);
- 获取指定日期时间
LocalDate specDatefromString = LocalDate.parse(“2014-12-12”);
LocalDate specDate = LocalDate.of(2014, 2, 20);
specDate = LocalDate.ofYearDay(2015, 100);
specDate = LocalDate.ofEpochDay(200);//自1970年1月1日起200天后的日期
- 获取今天是今年的第几天
int dayOfYear = LocalDate.now().getDayOfYear();
- 上个月最后一天
LocalDate date = LocalDate.now();
// 不用考虑是28、29、30还是31天
LocalDate lastDayOfMonth = date.with(TemporalAdjusters.lastDayOfMonth());
- 2015年11月第一个周一
LocalDate firstMondayInOneMonth = LocalDate.parse(“2015-11-11”).with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
- 日期加减与时间间隔
LocalTime time = LocalTime.now();
// 当前时间加20分钟
LocalTime timeAfterPlus = time.plusMinutes(20);
// 当前时间减2小时
LocalTime timeAfterMinus = time.minusHours(2);
// 两个时间间隔(单位:分钟),如第二个参数比第一个大,结果为负数
long duration = ChronoUnit.MINUTES.between(time, timeAfterPlus);
- 获取两个日期间的距离
LocalDate date = LocalDate.now();
Period period = Period.between(LocalDate.of(2014, 2, 10), date);
- 日期判断
LocalDate date = LocalDate.now();
LocalDate date1 = LocalDate.now();
// 判断是否相等
boolean isEqual = date.equals(date1);
// 判断是否在另一个日期之前
boolean isBefore = date.isBefore(date1);
// 判断是否为闰年
boolean isLeapYear = date.isLeapYear();
- 查看时区
// 获得所有时区
Set<String> allZone = ZoneId.getAvailableZoneIds();
ZoneId zone = ZoneId.systemDefault();
// 获得美国时间
ZoneId zoneInUSA = ZoneId.of(“America/New_York”);
LocalTime timeInUSA = LocalTime.now(zoneInUSA);
- 时间戳转换
- 将时间戳转换为日期
Instant second = Instant.ofEpochSecond(1234567890L);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”);
// 等同于 formatter.format(LocalDateTime.ofInstant(second, ZoneId.systemDefault()));
String time = LocalDateTime.ofInstant(second, ZoneId.systemDefault()).format(formatter);
// 另一种方法
LocalDateTime now = LocalDateTime.ofEpochSecond(12468312, 0, ZoneOffset.of("+8"));
- 日期转换为时间戳
// 第一种方式
Instant instant1 = LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant();
// 第二种方式
OffsetDateTime offsetTime = OffsetDateTime.now(ZoneId.systemDefault ());
ZoneOffset offset = offsetTime.getOffset();
Instant instant2 = LocalDateTime.now().toInstant(offset);
// 获得绝对秒
long millisecond = instant1.getEpochSecond();