人类时间

Wu Jun 2020-01-03 10:43:49
Categories: > > Tags:

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)运算

  1. 加减
plus、minus(Days,Weeks,Months,Years);
  1. 替换
    所有的数值必须合法;

如果当月当天是闰年 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());