天天看点

Java 8 日期API

Java 8 中的日期API相比以前更为简洁,辨识度高,而且都是线程安全的。掌握常用的时间类方法有时可以节省许多额外的工作。关于各个类的介绍可以参考Java 8新特性(四):新的时间和日期API

值得注意的是,LocalTime 、LocalDate 与 LocalDateTime 类的构造器都是 private,这里用了静态工厂方法(static factory methods)。静态工厂方法相比传统的构造器有如下优点(参考Effective Java第二版):

  1. 静态工厂方法在方法命名上更具有可读性
  2. 静态工厂方法可以在被调用的时候返回同一个对象,而不是每次都构建一个新的对象
  3. 静态工厂方法可以返回该类型的子类对象
  4. 静态工厂方法可以简化参数化类型的对象创建

关于第四点,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);

  • 时间戳转换
  1. 将时间戳转换为日期

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"));

  1. 日期转换为时间戳

// 第一种方式

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();