Java API 中有两种人类时间,本地日期/时间和时区时间。本地日期/时间无时区,而时区常常造成困扰,除非确实想要表示绝对时间的实例,最好都使用本地日期/时间。
1 本地日期/时间
1.1 LocalDate
LocalDate 是带有年、月、日的日期
1)构造
LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(1994, 5, 21);
LocalDate nDayOfYear = LocalDate.ofYearDay(2018, 300);
LocalDate dayFromEpoch = LocalDate.ofEpochDay(365);
LocalDate churchBirthday = LocalDate.parse("1803-06-14");
2)日期属性
getYear()
getMonth() // 月份(英文[enum]表示)
getMonthValue() // 月份(数值表示, 从1开始)
getDayOfMonth()
getDayOfYear() // 当天所在这一年的第几天
getDayOfWeek() // 星期几,枚举DayOfWeek的某个值
lengthOfYear() // 当年的天数
lengthOfMonth() //当月的天数
toEpochDay() // 与时间纪元相差的天数
toString() // yyyy-MM-dd
3)运算
- 加减
plus、minus(Days,Weeks,Months,Years);
- 替换
所有的数值必须合法;
如果当月当天是闰年 2 月 29 日,替换年份为非闰年,则会变成 2 月 28 日;
withDayOfMonth();
withDayOfYear();
withMonth();
withYear();
4)判断
isBefore()
isAfter()
isEqual()
isLeapYear()//是否是闰年
1.2 Period
本地日期之间的时长是 Period,表示流逝的年、月或日的数量
1)获取下一年生日
支持闰年
birthday.plus(Period.ofYears(1));
2)获取日期区间
today.until(birthday, ChronoUnit.DAYS);//xxx天
1.3 TemporalAdjuster
日期调整器 TemporalAdjuster 类提供了大量用于常见调整的静态方法。可将调整方法传给 with 方法。
LocalDate firstTuesday = LocalDate.of(year, month, 1).with(TemporalAdjusters.newxtOrSame(DayOfWeek.TUESDAY));
1)自带的日期调整期
next(weekday), previous(weekday)//下一个、上一个星期日起
nextOrSame(weekday)、previousOrSame(weekday)//从给定日期开始的下一个或上一个给定星期日期
dayOfWeekInMonth(n, weekday)//月份中第n个weekday
lastInMonth(weekday)//月份中最后一个weekday
firstDayOfMonth()、firstDayOfNextMonth()、firstDayOfNextYear()
lastDayOfMonth()、lastDayOfYear()
2)自定义日期调整期
TemporalAdjuster NEXT_WORKDAY = TemporalAdjuster.ifDateAdjuster(w ->
{
LocalDate result = w;
do{
result = result.plausDays(1);
}while(result.getDayOfWeek().getValue() >= 6);
return result;
}
);
1.4 LocalTime
LocalTime 表示当前时刻,如 15:30:30。不关心AM/PM,交给格式器解决
1)构造
LocalTime rightNow = LocalTime.now();// 11:09:09.240
LocalTime time = LocalTime.of(22, 30);// 22:30:00
LocalTime time = LocalTime.of(22, 30, 1);// 22:30:01
LocalTime mid = LocalTime.parse("12:00:00.345"); // 12:00:00.345
2)获取
getHour、getMinute、getSecond、getNano
3)运算
plus、minus(Hours,Minutes,Seconds,Nanos)
with(Hour,Minute,Second,Nano)
4)判断
isBefore、isAfter
1.5 LocalDateTime
LocalDateTime 类表示日期与时间,适合存储固定时区的时间点。
构造
final LocalDateTime datetime = LocalDateTime.now();//2014-04-12T11:37:52.309
final LocalDateTime datetimeFromClock =
2 时区时间
2.1 ZonedDateTime
ZonedDateTime 许多方法都与 LocalDateTime 相同,要特别注意跨越夏令时,使用 Preiod
1)构造
ZonedDateTime zonedDatetime = ZonedDateTime.now();//2014-04-12T11:47:01.017-04:00[America/New_York]
ZonedDateTime zonedDatetimeFromZone = ZonedDateTime.now( ZoneId.of("America/Los_Angeles") );//2014-04-12T08:47:01.017-07:00[America/Los_Angeles]
ZonedDateTime apollolaunch = ZonedDateTime.of(1969, 7, 16, 9, 32, 0, 0,ZoneId.of("America/New_York"));
2)时刻转换
Instant instant = apollolaunch.toInstant();
ZonedDateTime z = Instant.atZone(ZoneId.of("UTC"))
LocalDate yesterday = LocalDate.now().plusDays(-1);
ZonedDateTime zdt = yesterday.atStartOfDay(ZoneId.of("Asia/Shanghai"));
Date yesterdayDate = Date.from(zdt.toInstant());