前言 假设你想获取当前时间,那么你肯定看过这样的代码publicstaticvoidmain(String〔〕args){DatedatenewDate(System。currentTimeMillis());System。out。println(date。getYear());System。out。println(date。getMonth());System。out。println(date。getDate());} 获取年份,获取月份,获取。。日期? 运行一下121927 怎么回事?获取年份,日期怎么都不对,点开源码发现Returnsavaluethatistheresultofsubtracting1900fromtheyearthatcontainsorbeginswiththeinstantintimerepresentedbythiscodeDateobject,asinterpretedinthelocaltimezone。returntheyearrepresentedbythisdate,minus1900。seejava。util。CalendardeprecatedAsofJDKversion1。1,replacedbyCalendar。get(Calendar。YEAR)1900。DeprecatedpublicintgetYear(){returnnormalize()。getYear()1900;}code 原来是某个对象值减去了1900,注释也表示,返回值减去了1900,难道我们每次获取年份需要在加上1900?注释也说明了让我们用Calendar。get()替换,并且该方法已经被废弃了。点开getMonth()也是一样,返回了一个0到11的值。getDate()获取日期?不应该是getDay()吗?老外的day都是sunday、monday,getDate()才是获取日期。再注意到这些api都是在1。1的时候被废弃了,私以为是为了消除getYear减去1900等这些歧义。收Calendar日历类publicstaticvoidmain(String〔〕args){CalendarcalendarCalendar。getInstance();intyearcalendar。get(Calendar。YEAR);intmonthcalendar。get(Calendar。MONTH);intdomcalendar。get(Calendar。DAYOFMONTH);intdoycalendar。get(Calendar。DAYOFYEAR);intdowcalendar。get(Calendar。DAYOFWEEK);intdowimcalendar。get(Calendar。DAYOFWEEKINMONTH);System。out。println(year年month月);System。out。println(dom日);System。out。println(doy日);System。out。println(dow日);System。out。println(dowim);} 打印(运行时间2021年10月27日星期三晴)2021年9月27日300日4日4 问:月份怎么是上个月的? 答:是为了计算方便,约是0到11之间的值。 问:计算方便? 答:比如月份从1月开始,增加一个月,12月113,没有13月。假设区域,(121)121正好为1月,那11月增加一个月,(111)120,这就有问题了。所以为了计算方便1月,返回了0值。date。getMonth()也是一个道理。问:那下面的DAYOFXXX又是什么意思? 答:猜!根据结果猜。 Calendar。DAYOFMONTH在这个月的这一天 Calendar。DAYOFYEAR在这一年的这一天 Calendar。DAYOFWEEK在这一周的这一天 Calendar。DAYOFWEEKINMONTH在这一个月这一天在第九周 到这里Calendar。DAYOFWEEK为什么是4,你肯定也猜到了 Calendar。HOUR Calendar。HOUROFDAY Calendar。SECOND 。。。其他的你肯定也会用了LocalDate本地日期类LocalDatelocalDateLocalDate。now();System。out。println(当前日期:localDate。getYear()年localDate。getMonthValue()月localDate。getDayOfMonth()日);结果当前日期:2021年10月27日 也可以通过LocalDate。of(年,月,日)去构造LocalDatepluslocalDatelocalDate。plusDays(1);增加一天LocalDatepluslocalDatelocalDate。plusYears(1);增加一年 其他apiLocalDate。isBefore(LocalDate);LocalDate。isAfter();LocalDate。isEqual(); 也就是对两个日期的判断,是在前、在后、或者相等。LocalTime本地时间类LocalTimelocalTimeLocalTime。now();System。out。println(当前时间:localTime。getHour()hlocalTime。getSecond()mlocalTime。getMinute()s); LocalDate和LocalTime都有类似作用的api LocalDate。plusDays(1)增加一天 LocalTime。plusHours(1)增加一小时等等 其他apiLocalTime。isBefore(LocalTime);LocalTime。isAfter(); 对两个时间的判断。肯定碰到过一个需求,今天离活动开始时间还剩多少天。LocalDateTime本地日期时间类publicfinalclassLocalDateTime。。。{privatefinalLocalDprivatefinalLocalT} LocalDateTimeLocalDateLocalTime懂得都懂Instant类 Instant是瞬间,某一时刻的意思Instant。ofEpochMilli(System。currentTimeMillis())Instant。now() 通过Instant可以创建一个瞬间对象,ofEpochMilli()可以接受某一个瞬间,比如当前时间,或者是过去、将来的一个时间。 比如,通过一个瞬间创建一个LocalDateTime对象LocalDateTimenowLocalDateTime。ofInstant(Instant。ofEpochMilli(System。currentTimeMillis()),ZoneId。systemDefault());System。out。println(当前日期:now。getYear()年now。getMonthValue()月now。getDayOfMonth()日);Period类 Period是时期,一段时间的意思 Period有个between方法专门比较两个日期的LocalDatestartDateLocalDateTime。ofInstant(Instant。ofEpochMilli(1601175465000L),ZoneId。systemDefault())。toLocalDate();1601175465000是202092710:57:45PeriodpPeriod。between(startDate,LocalDate。now());System。out。println(目标日期距离今天的时间差:p。getYears()年p。getMonths()个月p。getDays()天);目标日期距离今天的时间差:1年1个月1天 看一眼源码publicstaticPeriodbetween(LocalDatestartDateInclusive,LocalDateendDateExclusive){returnstartDateInclusive。until(endDateExclusive);}publicPerioduntil(ChronoLocalDateendDateExclusive){LocalDateendLocalDate。from(endDateExclusive);longtotalMonthsend。getProlepticMonth()this。getProlepticMonth();safeintdaysend。daythis。if(totalMonths0days0){totalMLocalDatecalcDatethis。plusMonths(totalMonths);days(int)(end。toEpochDay()calcDate。toEpochDay());safe}elseif(totalMonths0days0){totalMdaysend。lengthOfMonth();}longyearstotalMonths12;safeintmonths(int)(totalMonths12);safereturnPeriod。of(Math。toIntExact(years),months,days);} 他只接受两个LocalDate对象,对时间的计算,算好之后返回Period对象Duration类 Duration是期间持续时间的意思上代码LocalDateTimeendLocalDateTime。ofInstant(Instant。ofEpochMilli(System。currentTimeMillis()),ZoneId。systemDefault());LocalDateTimestartLocalDateTime。ofInstant(Instant。ofEpochMilli(1601175465000L),ZoneId。systemDefault());DurationdurationDuration。between(start,end);System。out。println(开始时间到结束时间,持续了duration。toDays()天);System。out。println(开始时间到结束时间,持续了duration。toHours()小时);System。out。println(开始时间到结束时间,持续了duration。toMillis()1000秒); 可以看到between也接受两个参数,LocalDateTime对象,源码是对两个时间的计算,并返回对象。对象转换 再贴点apilongLocalDateTimeLocalDateTime。ofInstant(Instant。ofEpochMilli(timestamp),ZoneId。systemDefault())StringLocalDateTimeDateTimeFormatterdateTimeFormatter1DateTimeFormatter。ofPattern(yyyyMMddHH:mm:ss);LocalDateTime。parse(2021102800:00:00,dateTimeFormatter1);LocalDateTimelongLocalDateTime对象。atZone(ZoneId。systemDefault())。toInstant()。toEpochMilli();LocalDateTimeStringDateTimeFormatterdateTimeFormatter1DateTimeFormatter。ofPattern(yyyyMMddHH:mm:ss);LocalDateTime对象。format(dateTimeFormatter1) 对象转换几乎都涵盖了,里面有个时区对象,这个一般用默认时区。总结 用LocalDate、LocalTime、LocalDateTime代替了Date类。Date管日期,Time管时间 LocalDateTimeLocalDateLocalTime Period只能用LocalDate Duration持续时间,所以LocalDate、LocalTime、LocalDateTime都能处理 至于Calendar日历类,这里面的api,都是针对日历的,比如这个月的第一天是星期几。 总体来说,都是api的使用,非常清晰,废弃date。getMonth()等,使用localDate。getMonthValue()来获取几月,更易理解,更易贴合使用。代码都贴在了github上了