Java 8之前的库对日期和时间的支持并不太理想,为了解决这个问题,Java 8中引入了一套全新的时间日期API,位于java.time
路径下。
LocalDate
LocalDate
类型包含了年月日信息,下面举些LocalDate
的使用示例:
public static void main(String[] args) {
LocalDate date = LocalDate.of(2020, 11, 04);
// 年
int year = date.getYear();
// 月
int month = date.getMonth().getValue();
// 日
int day = date.getDayOfMonth();
// 查看该月有多少天
int days = date.lengthOfMonth();
// 是否是闰年
boolean isLeap = date.isLeapYear();
}
可以使用LocalDate.now()
获取当天的日期信息:
public static void main(String[] args) {
// 查看当天 年月日
LocalDate today = LocalDate.now();
}
除了调用LocalDate
的getYear
方法外,我们也可以使用ChronoField
枚举类型来实现相同的功能:
public static void main(String[] args) {
LocalDate date = LocalDate.of(2020, 11, 04);
int year = date.get(ChronoField.YEAR);
int month = date.get(ChronoField.MONTH_OF_YEAR);
int day = date.get(ChronoField.DAY_OF_MONTH);
// 当前日期属于该月第几周
int weekOfMonth = date.get(ChronoField.ALIGNED_WEEK_OF_MONTH);
}
ChronoField
枚举类型包含了诸多的属性可供选择:
我们也可以修改LocalDate
对象:
public static void main(String[] args) {
LocalDate date = LocalDate.of(2020, 11, 04);
LocalDate date1 = date.withDayOfMonth(22);
LocalDate date2 = date.with(ChronoField.DAY_OF_MONTH, 22);
LocalDate date3 = date.withYear(2019);
LocalDate date4 = date.plusDays(5);
LocalDate date5 = date.plus(5, ChronoUnit.DAYS);
LocalDate date6 = date.minusYears(10);
}
运行结果如下所示,当然我在运行的时候是进行了在控制台输出打印的我只是没有给出来:
2020-11-22
2020-11-22
2019-11-04
2020-11-09
2020-11-09
2010-11-04
TemporalAdjusters
类提供了许多静态方法来修改LocalDate
对象。当我们需要获取下一个星期一,按当前时间获取上一个星期六,本月的最后一天等信息时,TemporalAdjusters
类便可派上用场:
public static void main(String[] args) {
LocalDate date = LocalDate.of(2020, 11, 04);
LocalDate date1 = date.with(nextOrSame(DayOfWeek.MONDAY));
LocalDate date2 = date.with(lastDayOfMonth());
LocalDate date3 = date.with(previous(DayOfWeek.SATURDAY));
}
运行结果:
2020-11-09
2020-11-30
2020-10-31
可参考2020年11月4日的日历来理解上面的结果:
我们还可以对LocalDate
进行格式化操作:
public static void main(String[] args) {
LocalDate date = LocalDate.of(2020, 11, 04);
String str1 = date.format(DateTimeFormatter.BASIC_ISO_DATE);
String str2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String str3 = date.format(dtf);
LocalDate date1 = LocalDate.parse(str3, dtf);
}
运行结果如下:
20201104
2020-11-04
2020-11-04
2020-11-04
LocalDate和下面要介绍的LocalTime,LocalDateTime之间共享了许多类似的方法,上面介绍的LocalDate修改、格式化等方法通用适用于LocalTime和LocalDateTime。
LocalTime
LocalTime
和LocalDate
类似,区别在于LocalTime
包含的是时分秒(毫秒)信息。举些LocalTime
的例子:
public static void main(String[] args) {
LocalTime time = LocalTime.of(20, 13, 54);
int hour = time.getHour();
int minute = time.getMinute();
int second = time.getSecond();
}
运行结果如下所示:
20
13
54
LocalDate
和LocalTime
都可以通过字符串来创建:
public static void main(String[] args) {
LocalDate date = LocalDate.parse("2018-04-20");
LocalTime time = LocalTime.parse("20:13:54");
}
LocalDateTime
LocalDateTime
是LocalDate
和LocalTime
的组合形式,包含了年月日时分秒信息。举些LocalDateTime
的使用示例:
public static void main(String[] args) {
LocalDate date = LocalDate.parse("2018-04-20");
LocalTime time = LocalTime.parse("20:13:54");
LocalDateTime ldt1 = LocalDateTime.of(2018, 4, 20, 20, 13, 54);
LocalDateTime ldt2 = LocalDateTime.of(date, time);
}
运行结果如下所示:
2018-04-20T20:13:54
2018-04-20T20:13:54
LocalDateTime
可以转换为LocalDate
和LocalTime
,转换后包含的信息减少了:
public static void main(String[] args) {
LocalDate date = LocalDate.parse("2018-04-20");
LocalTime time = LocalTime.parse("20:13:54");
LocalDateTime ldt1 = LocalDateTime.of(2018, 4, 20, 20, 13, 54);
LocalDateTime ldt2 = LocalDateTime.of(date, time);
LocalDate date1 = ldt1.toLocalDate();
LocalTime time1 = ldt1.toLocalTime();
}
运行结果如下:
2018-04-20
20:13:54
同样的,LocalDate
和LocalTime
也可以转换为LocalDateTime
,只需要补上日期或者时间即可:
public static void main(String[] args) {
LocalDate date = LocalDate.parse("2018-04-20");
LocalTime time = LocalTime.parse("20:13:54");
LocalDateTime ldt1 = date.atTime(time);
LocalDateTime ldt2 = date.atTime(20, 13, 54);
LocalDateTime ldt3 = time.atDate(date);
}
运行结果如下所示:
2018-04-20T20:13:54
2018-04-20T20:13:54
2018-04-20T20:13:54
Duration
Duration
用于计算两个LocalTime
或者LocalDateTime
的时间差,例如:
public static void main(String[] args) {
LocalTime time1 = LocalTime.of(23, 20, 59);
LocalTime time2 = LocalTime.of(23, 59, 59);
Duration duration = Duration.between(time1, time2);
long seconds = duration.getSeconds();
}
运行结果如下所示:
2340
time1和time2之间相差了2340秒。
手动创建Duration
对象:
public static void main(String[] args) {
Duration threeMinutes = Duration.ofMinutes(3);
// 创建了一个3分钟的Duration,两种创建方式等价
threeMinutes = Duration.of(3, ChronoUnit.MINUTES);
}
Period
Period
用于计算两个LocalDate
之间的时长。举些例子:
public static void main(String[] args) {
LocalDate date1 = LocalDate.of(2018, 4, 20);
LocalDate date2 = LocalDate.of(2018, 5, 21);
Period period = Period.between(date1, date2);
int monthsBetween = period.getMonths();
int daysBetween = period.getDays();
}
运行结果如下所示:
1
1
2018-04-20和2018-05-21之间月份相差1,天数相差1。
同样的,我们也可以手动创建Period
对象:
public static void main(String[] args) {
Period tenDays = Period.ofDays(10);
Period threeWeeks = Period.ofWeeks(3);
Period twoYearsSixMonthsOneDay = Period.of(2, 6, 1);
}
其他一些常用的方法
比较两个时间的先后
public static void main(String[] args) {
LocalDate date1 = LocalDate.of(2020, 11, 04);
LocalDate date2 = LocalDate.of(2018, 4, 21);
date1.isEqual(date2);
date1.isAfter(date2);
date1.isBefore(date2);
}
运行结果如下所示:
false
true
false
MonthDay类的使用
MonthDay
只包含月日信息,可以用于存放类似于生日,结婚纪念日等信息。举个使用MonthDay
的例子:
public static void main(String[] args) {
LocalDate birthday = LocalDate.of(2001, 8, 10);
MonthDay monthDay = MonthDay.of(birthday.getMonth(), birthday.getDayOfMonth());
MonthDay currentMonthDay = MonthDay.from(LocalDate.now());
if (currentMonthDay.equals(monthDay)) {
System.out.println("happy birthday!");
}
}
假如用户的生日是2001年8月10号,那么可以通过这种方法来判断今天是否是用户的生日,如果是的话便发送生日祝福。同样的也有YearMonth
类。
Java 8 新的日期时间API还提供了不同时区和历法的获取方法,由于较少使用而且不易于理解,这里不再列出。????