干掉Date,Java8 LocalDate 真香_jave8 date 优缺点

78 阅读8分钟

}


![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/cc1f5ac579db43e8b9f31a0a857978d4~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDgwNDUxMTkwMTI=:q75.awebp?rk3s=f64ab15b&x-expires=1772721246&x-signature=y1aLOsUdmWJQ2J9xD1H0y6GfMOA%3D)


#### 7.在现有的时间上增加小时


Java 8 提供了更好的 plusHours() 方法替换 add() ,并且是兼容的。注意,这些方法返回一个全新的LocalTime实例,由于其不可变性,返回后一定要用变量赋值。



//增加小时 public void plusHours(){     LocalTime time = LocalTime.now();     LocalTime newTime = time.plusHours(2); // 增加两小时     System.out.println("Time after 2 hours : " +  newTime); }


![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/979643c17dc54e19be761affb143131e~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDgwNDUxMTkwMTI=:q75.awebp?rk3s=f64ab15b&x-expires=1772721246&x-signature=cqgZFrJ9ns7RVaqYCjiJy4YdAsg%3D)


#### 8.如何计算一个星期之后的日期


和上个例子计算两小时以后的时间类似,这个例子会计算一周后的日期。LocalDate日期不包含时间信息,它的plus()方法用来增加天、周、月,ChronoUnit类声明了这些时间单位。由于LocalDate也是不变类型,返回后一定要用变量赋值。


可以用同样的方法增加1个月、1年、1小时、1分钟甚至一个世纪,更多选项可以查看Java 8 API中的ChronoUnit类。



//如何计算一周后的日期 public void nextWeek(){     LocalDate today = LocalDate.now();     LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS);    //使用变量赋值     System.out.println("Today is : " + today);     System.out.println("Date after 1 week : " + nextWeek); }


![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/7498ff110e834b39bccc10d35bc894a2~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDgwNDUxMTkwMTI=:q75.awebp?rk3s=f64ab15b&x-expires=1772721246&x-signature=QVW6ItMMZHVu8ekruSRSR0nKFfQ%3D)


#### 9.计算一年前或一年后的日期


接着上面的例子中我们通过 LocalDate 的 plus() 方法增加天数、周数或月数,这个例子我们利用 minus() 方法计算一年前的日期。



//计算一年前或一年后的日期 public void minusDate(){     LocalDate today = LocalDate.now();     LocalDate previousYear = today.minus(1, ChronoUnit.YEARS);     System.out.println("Date before 1 year : " + previousYear);

    LocalDate nextYear = today.plus(1, ChronoUnit.YEARS);     System.out.println("Date after 1 year : " + nextYear); }


![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/92c2e49b524c44cc82825646d278f97d~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDgwNDUxMTkwMTI=:q75.awebp?rk3s=f64ab15b&x-expires=1772721246&x-signature=EUwSPTgpRV7QCgyR2p8uVY9T7d4%3D)


#### 10.使用Java 8的Clock时钟类


Java 8增加了一个 Clock 时钟类用于获取当时的时间戳,或当前时区下的日期时间信息。以前用到System.currentTimeInMillis() 和 TimeZone.getDefault() 的地方都可用Clock替换。



public void clock(){     // 根据系统时间返回当前时间并设置为UTC。     Clock clock = Clock.systemUTC();     System.out.println("Clock : " + clock);

    // 根据系统时钟区域返回时间     Clock defaultClock = Clock.systemDefaultZone();     System.out.println("Clock : " + clock); }


![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/043f81660bec496280a0ac42bf298707~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDgwNDUxMTkwMTI=:q75.awebp?rk3s=f64ab15b&x-expires=1772721246&x-signature=Co6vjAdixYfUilT2MhX%2F70%2B%2Ba68%3D)


#### 11.判断日期是早于还是晚于另一个日期


LocalDate 类有两类方法 isBefore() 和 isAfter() 用于比较日期。调用 isBefore() 方法时,如果给定日期小于当前日期则返回 true。



//如何用Java判断日期是早于还是晚于另一个日期 public void isBeforeOrIsAfter(){     LocalDate today = LocalDate.now(); 

    LocalDate tomorrow = LocalDate.of(2018, 1, 29);     if(tomorrow.isAfter(today)){         System.out.println("Tomorrow comes after today");     }

    //减去一天     LocalDate yesterday = today.minus(1, ChronoUnit.DAYS);

    if(yesterday.isBefore(today)){         System.out.println("Yesterday is day before today");     } }


![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/1a510da5db994ee5b6ccd4755b0f0fe2~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDgwNDUxMTkwMTI=:q75.awebp?rk3s=f64ab15b&x-expires=1772721246&x-signature=3O6SBtu4AFcH%2BIKZd8vWNd8x4yQ%3D)


#### 12.处理时区


Java 8不仅分离了日期和时间,也把时区分离出来了。现在有一系列单独的类如 ZoneId 来处理特定时区,ZoneDateTime 类来表示某时区下的时间。



//获取特定时区下面的时间 public void getZoneTime(){     //设置时区     ZoneId america = ZoneId.of("America/New_York");

    LocalDateTime localtDateAndTime = LocalDateTime.now();

    ZonedDateTime dateAndTimeInNewYork  = ZonedDateTime.of(localtDateAndTime, america );     System.out.println("现在的日期和时间在特定的时区 : " + dateAndTimeInNewYork); }


![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/14cb567d739c4524909ceaea151ae2b7~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDgwNDUxMTkwMTI=:q75.awebp?rk3s=f64ab15b&x-expires=1772721246&x-signature=nVYS2eNUdaIehf%2Boi1VsdwflG%2Bo%3D)


#### 13.如何体现出固定日期


例如:表示信用卡到期这类固定日期。与 MonthDay 检查重复事件的例子相似,YearMonth 是另一个组合类,用于表示信用卡到期日、FD到期日、期货期权到期日等。


还可以用这个类得到 当月共有多少天,YearMonth 实例的 lengthOfMonth() 方法可以返回当月的天数,在判断2月有28天还是29天时非常有用。



//使用 YearMonth类处理特定的日期 public void checkCardExpiry(){     YearMonth currentYearMonth = YearMonth.now();     System.out.printf("Days in month year %s: %d%n", currentYearMonth, currentYearMonth.lengthOfMonth());

    YearMonth creditCardExpiry = YearMonth.of(2028, Month.FEBRUARY);     System.out.printf("Your credit card expires on %s %n", creditCardExpiry); }


![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/3dac36b4ad524d0cb75f150f111b7e69~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDgwNDUxMTkwMTI=:q75.awebp?rk3s=f64ab15b&x-expires=1772721246&x-signature=4szHBrfPxvVLeZAoGY4RrNva%2FSg%3D)


#### 14.检查闰年


LocalDate类有一个很实用的方法 isLeapYear() 判断该实例是否是一个闰年,如果你还是想重新发明轮子,这有一个代码示例,纯Java逻辑编写的判断闰年的程序。



//检查闰年 public void isLeapYear(){     LocalDate today = LocalDate.now();     if(today.isLeapYear()){         System.out.println("This year is Leap year");     }else {         System.out.println("2018 is not a Leap year");     } }


![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/bc693687ac294268b07f9a0ad8126cb4~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDgwNDUxMTkwMTI=:q75.awebp?rk3s=f64ab15b&x-expires=1772721246&x-signature=xpfYfXQEf1KFNKMu6HZixOxGuLk%3D)


#### 15.计算两个日期之间的天数和月数


有一个常见日期操作是计算两个日期之间的天数、周数或月数。在Java 8中可以用java.time.Period类来做计算。下面这个例子中,我们计算了当天和将来某一天之间的月数。


下面的例子:现在是一月份,距离到五月份,中间相隔3月



//计算两个日期之间的天数和月数 public void calcDateDays(){     LocalDate today = LocalDate.now();

    LocalDate java8Release = LocalDate.of(2018, Month.MAY, 14);

    Period periodToNextJavaRelease = Period.between(today, java8Release);

    System.out.println("Months left between today and Java 8 release : "                                            + periodToNextJavaRelease.getMonths() ); }


![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/eec0efe1a86d49939ec282b47e7172dd~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDgwNDUxMTkwMTI=:q75.awebp?rk3s=f64ab15b&x-expires=1772721246&x-signature=PoKDkWHDuovbQVC4%2BSvtibuL89A%3D)


#### 16.包含时差信息的日期和时间


ZoneOffset类用来表示时区,举例来说印度与GMT或UTC标准时区相差+05:30,可以通过ZoneOffset.of()静态方法来 获取对应的时区。一旦得到了时差就可以通过传入LocalDateTime和ZoneOffset来创建一个OffSetDateTime对象。



public void ZoneOffset(){     LocalDateTime datetime = LocalDateTime.of(2018, Month.FEBRUARY, 14, 19, 30);     ZoneOffset offset = ZoneOffset.of("+05:30");     OffsetDateTime date = OffsetDateTime.of(datetime, offset);       System.out.println("Date and Time with timezone offset in Java : " + date); }


![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/1f8ca8edad3b4be0a45b4086c36dd7af~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDgwNDUxMTkwMTI=:q75.awebp?rk3s=f64ab15b&x-expires=1772721246&x-signature=g5TPg2ZkEMC9RQL8hABNDwhNXGM%3D)


#### 17.获取当前的时间戳


Instant类有一个静态工厂方法now()会返回当前的时间戳,如下所示:



public void getTimestamp(){     Instant timestamp = Instant.now();     System.out.println("What is value of this instant " + timestamp); }


![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/c751328eef9b4b60b1404d3e70ca8ae4~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDgwNDUxMTkwMTI=:q75.awebp?rk3s=f64ab15b&x-expires=1772721246&x-signature=srQV1h8sRYQUDYa6j2f94Ufx6UM%3D)


#### 18.使用预定义的格式化工具去解析或格式化日期


Java 8引入了全新的日期时间格式工具,线程安全而且使用方便。它自带了一些常用的内置格式化工具。


下面这个例子使用了BASIC\_ISO\_DATE格式化工具将2018年2月10日格式化成20180210。



// 使用预定义的格式化工具去解析或格式化日期 public void formateDate(){     String dayAfterTommorrow = "20180210";     LocalDate formatted = LocalDate.parse(dayAfterTommorrow, DateTimeFormatter.BASIC_ISO_DATE);     System.out.printf("Date generated from String %s is %s %n", dayAfterTommorrow, formatted); }


![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/629328a301b2482d997d75344057922d~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDgwNDUxMTkwMTI=:q75.awebp?rk3s=f64ab15b&x-expires=1772721246&x-signature=3e7bVbC%2F%2FeXojkLqITqHLhIyL54%3D)


### 最后


最后附上全部代码



package com.wq.study.java8.date;

import java.time.Clock; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.Month; import java.time.MonthDay; import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.time.Period; import java.time.YearMonth; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.Date;

public class DateTest {

    //获取今天的日期     public void getCurrentDate(){         LocalDate today = LocalDate.now();         System.out.println("Today's Local date : " + today);

        //这个是作为对比         Date date = new Date();         System.out.println(date);     }

    //获取年、月、日信息     public void getDetailDate(){         LocalDate today = LocalDate.now();         int year = today.getYear();         int month = today.getMonthValue();         int day = today.getDayOfMonth();

        System.out.printf("Year : %d  Month : %d  day : %d t %n", year, month, day);     }

    //处理特定日期     public void handleSpecilDate(){         LocalDate dateOfBirth = LocalDate.of(2018, 01, 21);         System.out.println("The specil date is : " + dateOfBirth);     }

    //判断两个日期是否相等     public void compareDate(){         LocalDate today = LocalDate.now();         LocalDate date1 = LocalDate.of(2018, 01, 21);

        if(date1.equals(today)){             System.out.printf("TODAY %s and DATE1 %s are same date %n", today, date1);         }     }

    //处理周期性的日期     public void cycleDate(){         LocalDate today = LocalDate.now();         LocalDate dateOfBirth = LocalDate.of(2018, 01, 21);

        MonthDay birthday = MonthDay.of(dateOfBirth.getMonth(), dateOfBirth.getDayOfMonth());         MonthDay currentMonthDay = MonthDay.from(today);

        if(currentMonthDay.equals(birthday)){            System.out.println("Many Many happy returns of the day !!");         }else{            System.out.println("Sorry, today is not your birthday");         }     }

    //获取当前时间     public void getCurrentTime(){         LocalTime time = LocalTime.now();         System.out.println("local time now : " + time);     }

    //增加小时     public void plusHours(){         LocalTime time = LocalTime.now();         LocalTime newTime = time.plusHours(2); // 增加两小时         System.out.println("Time after 2 hours : " +  newTime);     }

    //如何计算一周后的日期     public void nextWeek(){         LocalDate today = LocalDate.now();         LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS);         System.out.println("Today is : " + today);         System.out.println("Date after 1 week : " + nextWeek);     }

    //计算一年前或一年后的日期     public void minusDate(){         LocalDate today = LocalDate.now();         LocalDate previousYear = today.minus(1, ChronoUnit.YEARS);         System.out.println("Date before 1 year : " + previousYear);

        LocalDate nextYear = today.plus(1, ChronoUnit.YEARS);         System.out.println("Date after 1 year : " + nextYear);     }

    public void clock(){         // 根据系统时间返回当前时间并设置为UTC。         Clock clock = Clock.systemUTC();         System.out.println("Clock : " + clock);

        // 根据系统时钟区域返回时间         Clock defaultClock = Clock.systemDefaultZone();         System.out.println("Clock : " + clock);     }

    //如何用Java判断日期是早于还是晚于另一个日期     public void isBeforeOrIsAfter(){         LocalDate today = LocalDate.now(); 

        LocalDate tomorrow = LocalDate.of(2018, 1, 29);         if(tomorrow.isAfter(today)){             System.out.println("Tomorrow comes after today");         }

        LocalDate yesterday = today.minus(1, ChronoUnit.DAYS);

        if(yesterday.isBefore(today)){             System.out.println("Yesterday is day before today");         }     }

    //时区处理     public void getZoneTime(){         //设置时区         ZoneId america = ZoneId.of("America/New_York");

        LocalDateTime localtDateAndTime = LocalDateTime.now();

        ZonedDateTime dateAndTimeInNewYork  = ZonedDateTime.of(localtDateAndTime, america );         System.out.println("现在的日期和时间在特定的时区 : " + dateAndTimeInNewYork);     }

    //使用 YearMonth类处理特定的日期     public void checkCardExpiry(){         YearMonth currentYearMonth = YearMonth.now();         System.out.printf("Days in month year %s: %d%n", currentYearMonth, currentYearMonth.lengthOfMonth());

        YearMonth creditCardExpiry = YearMonth.of(2028, Month.FEBRUARY);         System.out.printf("Your credit card expires on %s %n", creditCardExpiry);     }

    //检查闰年     public void isLeapYear(){         LocalDate today = LocalDate.now();         if(today.isLeapYear()){            System.out.println("This year is Leap year");         }else {             System.out.println("2018 is not a Leap year");         }     }

    //计算两个日期之间的天数和月数     public void calcDateDays(){         LocalDate today = LocalDate.now();

        LocalDate java8Release = LocalDate.of(2018, Month.MAY, 14);

        Period periodToNextJavaRelease = Period.between(today, java8Release);

        System.out.println("Months left between today and Java 8 release : "                                            + periodToNextJavaRelease.getMonths() );     }

    // 包含时差信息的日期和时间     public void ZoneOffset(){         LocalDateTime datetime = LocalDateTime.of(2018, Month.FEBRUARY, 14, 19, 30);         ZoneOffset offset = ZoneOffset.of("+05:30");         OffsetDateTime date = OffsetDateTime.of(datetime, offset);           System.out.println("Date and Time with timezone offset in Java : " + date);     }

    // 获取时间戳     public void getTimestamp(){         Instant timestamp = Instant.now();         System.out.println("What is value of this instant " + timestamp);     }

    // 使用预定义的格式化工具去解析或格式化日期     public void formateDate(){         String dayAfterTommorrow = "20180210";         LocalDate formatted = LocalDate.parse(dayAfterTommorrow, DateTimeFormatter.BASIC_ISO_DATE);         System.out.printf("Date generated from String %s is %s %n", dayAfterTommorrow, formatted);     }

    public static void main(String[] args) {         DateTest dt = new DateTest();

        dt.formateDate();     }

}