Java 8's new time and date library, you won't count me after reading these 20 cases! ! !

Java's handling of dates, calendars and time has always been criticized, especially its decision to define java.util.Date as modifiable and implement SimpleDateFormat to be non-thread-safe. It seems that Java has realized the need to provide better support for the time and date functions, which is also a good thing for the community that has become accustomed to using the Joda time and date library. The biggest advantage of this new time and date library is that it clearly defines some concepts related to time and date, for example, instantaneous time (Instant), duration (duration), date (date), time (time), time zone (Time-zone) and period (Period). At the same time, it also draws on some of the advantages of the Joda library, such as the distinction between human and machine understanding of time and date. Java 8 still uses the ISO calendar system, and unlike its predecessors, the classes in the java.time package are immutable and thread-safe. The new time and date API is located in the java.time package. Here are some of the key classes in it:

– Instant-it represents the timestamp

– LocalDate—Does not include a date at a specific time, such as 2014-01-14. It can be used to store birthdays, anniversaries, entry dates, etc.

– LocalTime——It represents the time without date

– LocalDateTime—It contains the date and time, but there is still no offset information or time zone.

– ZonedDateTime——This is a complete date and time including the time zone, and the offset is based on UTC/Greenwich Mean Time.

The new library also adds ZoneOffset and Zoned, which can provide better support for time zones. With the new DateTimeFormatter, date parsing and formatting have also become completely new. By the way, I wrote this article when Java was about to launch this new feature at this time last year, so you will find that the time in the example is still last year. If you run these examples, the values ​​they return are definitely correct.

How does Java 8 deal with time and date

Someone asked me what is the best way to learn a new library? My answer is to use it like that in actual projects. There will be various requirements in a real project, which will prompt developers to explore and research this new library. In short, only the task itself will really motivate you to explore and learn. The new date and time API of java 8 is the same. In order to learn this new library of Java 8, here I have created 20 task-oriented examples. Let's start with a simple task, such as how to use the Java 8 time and date library to represent today, and then further generate a complete date with time and time zone, and then study how to complete some more practical tasks, such as Develop a reminder application to find out how many days are left before certain dates such as birthdays, Sunday anniversaries, the next billing date, the next premium date, or the expiration date of the credit card.

Example 1 How to get today's date in Java 8 There is a class called LocalDate in Java 8, which can be used to represent today's date. This class is slightly different from java.util.Date because it only contains the date, not the time. Therefore, if you only need to represent the date without the time, you can use it.

LocalDate today = LocalDate.now(); System.out.println("Today's Local date : " + today); 

Output 
Today's Local date : 2014-01-14

You can see that it created today's date without time information. It also formats the date before outputting it. Unlike the previous Date class, the printed data is all unformatted.

Example 2 How to get the current year, month, and day in Java 8 The LocalDate class provides some convenient methods that can be used to extract the year, month, day and other date attributes. Using these methods, you can get any date attributes you need, instead of using classes like java.util.Calendar:

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); 

Output 
Today's Local date : 2014-01-14 
Year : 2014 Month : 1 day : 14 

As you can see, obtaining year and month information in Java 8 is very simple, just use the corresponding getter method, no need to remember, very intuitive. You can compare it with the old way of getting the current year, month, and day in Java.

Example 3 How to get a specific date in Java 8 In the first example, we saw that it is very simple to generate today's date through the static method now(), but through another very useful factory method LocalDate.of (), you can create any date, it accepts the parameters of year, month, and day, and then returns an equivalent LocalDate instance. The good news about this method is that it doesn't make any mistakes in the previous API. For example, the year can only start from 1900, the month must start from 0, and so on. The date here is what you write. For example, in the following example, it represents January 14. There is no hidden logic.

LocalDate dateOfBirth = LocalDate.of(2010, 01, 14); 
System.out.println("Your Date of birth is : " + dateOfBirth); 

Output : Your Date of birth is : 2010-01-14

It can be seen that the created date is exactly what we wrote, January 14, 2014.

Example 4 How to check whether two dates are equal in Java 8 If speaking of the actual task of processing time and date in reality, it is common to check whether two dates are equal. You may often encounter to judge whether today is a special day, such as a birthday, an anniversary, or a holiday. Sometimes, a date will be given to you to check if it is a certain day, such as a holiday. The following example will help you accomplish this type of task in Java 8. As you might expect, LocalDate overrides the equals method to compare dates, as shown below:

LocalDate date1 = LocalDate.of(2014, 01, 14); if(date1.equals(today)){ 
    System.out.printf("Today %s and date1 %s are same date %n", today, date1); 
} 

Output 
today 2014-01-14 and date1 2014-01-14 are same date

In this example, the two dates we compare are equal. At the same time, if you get a formatted date string in the code, you have to parse it into a date before you can compare it. You can compare this example with the way of comparing dates before Java, and you will find that it is really cool.

Example 5 How to check for recurring events in Java 8, such as birthdays . Another actual task related to time and date in Java is to check recurring events, such as monthly billing day, wedding anniversary, and monthly repayment day Or the days when insurance premiums are paid each year. If you work in an e-commerce company, then there must be such a module, which will send birthday wishes to users and send them greetings on every important holiday, such as Christmas, Thanksgiving, or in India. It's Deepawali (Deepawali). How to determine whether it is a holiday or a repeating event in Java? Use the MonthDay class. This class is a combination of month and day and does not contain year information, which means you can use it to represent some days that recur every year. Of course, there are some other combinations, such as the YearMonth class. It is immutable and thread-safe like other classes in the new time and date library, and it is also a value class. Let's take an example to see how to use MonthDay to check a duplicate date:

LocalDate dateOfBirth = LocalDate.of(2010, 01, 14); 
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"); 
} 

Output: Many Many happy returns of the day !!

Although the year is different, today is the day of the birthday, so you will see a birthday greeting in the output. You can adjust the system time and run this program to see if it can remind you when your next birthday is. You can also try to write a JUnit unit test with your next birthday to see if the code runs correctly.

Example 6 How to get the current time in Java 8

This is very similar to getting the current date in the first example. This time we use a class called LocalTime, which is a time without a date and is a close relative of LocalDate. Here you can also use the static factory method now() to get the current time. The default format is hh:mm:ss:nnn, where nnn is nanoseconds. You can compare it with how to get the current time before Java 8.

LocalTime time = LocalTime.now(); System.out.println("local time now : " + time);

Output 
local time now : 16:33:33.369 // in hour, minutes, seconds, nano seconds

As you can see, the current time does not contain the date, because LocalTime only has time and no date.

Example 7 How to increase the number of hours in time Many times we need to add hours, minutes or seconds to calculate the future time. Java 8 not only provides immutable and thread-safe classes, it also provides some more convenient methods such as plusHours() to replace the original add() method. By the way, these methods return a reference to a new LocalTime instance, because LocalTime is immutable, so don't forget to store this new reference.

LocalTime time = LocalTime.now(); 
LocalTime newTime = time.plusHours(2); // adding two hours 
System.out.println("Time after 2 hours : " + newTime); 

Output : 
Time after 2 hours : 18:33:33.369

You can see that the current time is 16:33:33.369 2 hours later. Now you can compare it with the old way of increasing or decreasing hours in Java. You can tell at a glance which way is better.

Example 8 How to get the date 1 week later This is similar to the previous example of getting the time 2 hours later, here we will learn how to get the date 1 week later. LocalDate is used to represent a date without time. It has a plus() method that can be used to add days, weeks, or months, and ChronoUnit is used to represent this time unit. Since LocalDate is also immutable, any modification operation will return a new instance, so don't forget to save it.

LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS); 
System.out.println("Today is : " + today); 
System.out.println("Date after 1 week : " + nextWeek); 


Output: 
Today is : 2014-01-14 
Date after 1 week : 2014-01-21

You can see what the date is after 7 days, which is one week later. You can use this method to add one month, one year, one hour, one minute, or even ten years. Check the ChronoUnit class in the Java API for more options.

Example 9 Date around one year This is a sequel to the previous example. In the above example, we learned how to use LocalDate's plus() method to add a day, week or month to a date. Now let's learn how to use the minus() method to find the day one year ago.

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

Output: 
Date before 1 year : 2013-01-14 
Date after 1 year : 2015-01-14

It can be seen that there are two years in total, one is 2013 and the other is 2015, which are the years before and after 2014.

Example 10 Using the clock in Java 8 Java 8 comes with a Clock class, you can use it to get the current instantaneous time, date or time in a certain time zone. You can use Clock to replace System.currentTimeInMillis() and TimeZone.getDefault() methods.

// Returns the current time based on your system clock and set to UTC. 
Clock clock = Clock.systemUTC(); 
System.out.println("Clock : " + clock); 

// Returns time based on system clock zone Clock defaultClock = 
Clock.systemDefaultZone(); 
System.out.println("Clock : " + clock); 

Output: 
Clock : SystemClock[Z] 
Clock : SystemClock[Z]

You can use the specified date to compare with this clock, such as the following:

public class MyClass { 
    private Clock clock; // dependency inject ... 

    public void process(LocalDate eventDate) { 

        if(eventDate.isBefore(LocalDate.now(clock)) { 
            ... 
        } 
    } 
}

This is very convenient if you need to process dates in different time zones.

Example 11 How to judge whether a certain date is before or after another date in Java This is also a common task in actual projects. How do you judge whether a certain date is before or after another date, or is exactly equal? In Java 8, the LocalDate class has an isBefore() and isAfter() methods that can be used to compare two dates. If the date on which the method is called is earlier than the given date, the isBefore() method will return true.

LocalDate tomorrow = LocalDate.of(2014, 1, 15); 、if(tommorow.isAfter(today)){ 
    System.out.println("Tomorrow comes after today"); 
} 
LocalDate yesterday = today.minus(1, DAYS); 
if(yesterday.isBefore(today)){ 
    System.out.println("Yesterday is day before today"); 
} 

Output: 
Tomorrow comes after today 
Yesterday is day before today

You can see that date comparison in Java 8 is very simple. No need to use another class like Calendar to accomplish similar tasks.

Example 12 Dealing with different time zones in Java 8 Java 8 not only separates date and time, but also time zone. There are already several sets of classes related to time zones. For example, ZoneId represents a specific time zone, and ZonedDateTime represents the time with a time zone. It is equivalent to the GregorianCalendar class before Java 8. Using this class, you can convert the local time to the corresponding time in another time zone, such as the following example:

// Date and time with timezone in Java 8 ZoneId america = ZoneId.of("America/New_York"); 
LocalDateTime localtDateAndTime = LocalDateTime.now(); 
ZonedDateTime dateAndTimeInNewYork = ZonedDateTime.of(localtDateAndTime, america ); 
System.out.println("Current date and time in a particular timezone : " + dateAndTimeInNewYork); 

Output : 
Current date and time in a particular timezone : 2014-01-14T16:33:33.373-05:00[America/New_York]

You can compare it with the previous method of converting local time to GMT time. By the way, just as before Java 8, don't make a mistake about the text corresponding to the time zone, otherwise you will encounter such an exception:

Exception in thread "main" java.time.zone.ZoneRulesException: Unknown time-zone ID: ASIA/Tokyo
        at java.time.zone.ZoneRulesProvider.getProvider(ZoneRulesProvider.java:272)
        at java.time.zone.ZoneRulesProvider.getRules(ZoneRulesProvider.java:227)
        at java.time.ZoneRegion.ofId(ZoneRegion.java:120)
        at java.time.ZoneId.of(ZoneId.java:403)
        at java.time.ZoneId.of(ZoneId.java:351)  

Example 13 How to represent a fixed date, such as the expiration time of a credit card. Just as MonthDay represents a recurring day, YearMonth is another combination, which represents the repayment date of a credit card, the expiration date of a fixed deposit, and options to Dates of this type. You can use this class to find out how many days there are in that month. The lengthOfMonth() method returns how many days are in this YearMonth instance. This is very useful for checking whether February is 28 days or 29 days.

YearMonth currentYearMonth = YearMonth.now(); System.out.printf("Days in month year %s: %d%n", currentYearMonth, currentYearMonth.lengthOfMonth()); 
YearMonth creditCardExpiry = YearMonth.of(2018, Month.FEBRUARY); 
System.out.printf("Your credit card expires on %s %n", creditCardExpiry); 

Output: 
Days in month year 2014-01: 31 
Your credit card expires on 2018-02  

Example 14 How to check for leap year in Java 8 This is nothing complicated. The LocalDate class has an isLeapYear() method that returns whether the year corresponding to the current LocalDate is a leap year. If you want to reinvent the wheel, you can take a look at this code, which is written purely in Java to determine whether a year is a leap year.

if(today.isLeapYear()){ 
    System.out.println("This year is Leap year"); 
}else { 
    System.out.println("2014 is not a Leap year"); 
} 


Output: 2014 is not a Leap year

You can check for a few more years to see if the results are correct. It is best to write a unit test to test for normal years and leap years.

Example 15 How many days and months are contained between two dates? Another common task is to calculate how many days, weeks or years are contained between two given dates. You can use the java.time.Period class to accomplish this function. In the following example, we will calculate a total of several months before the current date and a date in the future.

LocalDate java8Release = LocalDate.of(2014, Month.MARCH, 14); 
Period periodToNextJavaRelease = 
Period.between(today, java8Release); 
System.out.println("Months left between today and Java 8 release : " + periodToNextJavaRelease.getMonths() ); 

Output: 
Months left between today and Java 8 release : 2

As you can see, this month is January, and the release date of Java 8 is March, so there are two months apart.

Example 16 Date and time with time zone offset In Java 8, you can use the ZoneOffset class to represent a certain time zone. For example, India is GMT or UTC5:30, you can use its static method ZoneOffset.of() method to Get the corresponding time zone. As long as the offset is obtained, you can create an OffsetDateTime by taking the LocalDateTime and the offset.

LocalDateTime datetime = LocalDateTime.of(2014, Month.JANUARY, 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); 

Output : 
Date and Time with timezone offset in Java : 2014-01-14T19:30+05:30

You can see that the current time and date are associated with the time zone. Another point is that OffSetDateTime is mainly for machines to understand. If it is for people to see, you can use the ZoneDateTime class.

Example 17 How to get the current timestamp in Java 8 If you remember how to get the current timestamp before Java 8, now this is simply a piece of cake. The Instant class has a static factory method now() that can return the current timestamp, as follows:

Instant timestamp = Instant.now(); 
System.out.println("What is value of this instant " + timestamp); 

Output : 
What is value of this instant 2014-01-14T08:33:33.379Z

It can be seen that the current timestamp contains date and time, which is very similar to java.util.Date. In fact, Instant is the Date before Java 8. You can use the methods in these two classes to specify between these two types. For example, Date.from(Instant) is used to convert Instant to java.util.Date, and Date.toInstant() is used to convert Date to Instant.

Example 18 How to use a predefined formatter to parse/format the date in Java 8. Before Java 8, the formatting of time and date is a technical skill. Our good partner SimpleDateFormat is not thread-safe, but if you use it Formatting as a local variable is a bit cumbersome. Thanks to thread-local variables, this makes it useful in a multi-threaded environment, but Java has maintained this state for a long time. This time it introduces a new thread-safe date and time formatter. It also comes with some predefined formatters, including commonly used date formats. For example, in this example, we used the predefined BASIC_ISO_DATE format, which will format February 14, 2014 into 20140114.

String dayAfterTommorrow = "20140116"; 
LocalDate formatted = LocalDate.parse(dayAfterTommorrow, 
DateTimeFormatter.BASIC_ISO_DATE); 
System.out.printf("Date generated from String %s is %s %n", dayAfterTommorrow, formatted); 

Output : 
Date generated from String 20140116 is 2014-01-16

You can see that the generated date matches the value of the specified string, but the date format is slightly different.

Example 19 How to use a custom formatter to parse dates in Java In the above example, we used the built-in time and date formatter to parse date strings. Of course, the predefined formatter is really good, but sometimes you may still need to use a custom date format. At this time, you have to create a custom date formatter instance yourself. The date format in the example below is "MMM dd yyyy". You can pass in any pattern to the ofPattern static method() of DateTimeFormatter, and it will return an instance. The literal of this pattern is the same as in the previous example. For example, M still represents the month, and m is still the minute. Invalid mode will throw DateTimeParseException, but if it is a logical error, for example, when M should be used, m is used, so there is no way.

String goodFriday = "Apr 18 2014"; 
try { 
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd yyyy");     
    LocalDate holiday = LocalDate.parse(goodFriday, formatter); 
    System.out.printf("Successfully parsed String %s, date is %s%n", goodFriday, holiday); 
} catch (DateTimeParseException ex) { 
    System.out.printf("%s is not parsable!%n", goodFriday); 
    ex.printStackTrace(); 
} 

Output : 
Successfully parsed String Apr 18 2014, date is 2014-04-18

You can see that the value of the date does match the string passed in, but the format is different.

Example 20 How to format dates in Java 8 and convert them into strings In the previous two examples, although we used the DateTimeFormatter class, we mainly parse date strings. In this example, what we are going to do is just the opposite. Here we have an instance of the LocalDateTime class, we want to convert it into a formatted date string. This is by far the easiest and most convenient way to convert dates into strings in Java. The following example will return a formatted string. The same as the previous example, we still need to use the specified pattern string to create an instance of the DateTimeFormatter class, but it is not the parse method of the LocalDate class that is called, but its format() method. This method returns a string representing the current date, and the corresponding pattern is defined in the DateTimeFormatter instance passed in.

LocalDateTime arrivalDate = LocalDateTime.now(); 
try { 
    DateTimeFormatter format = DateTimeFormatter.ofPattern("MMM dd yyyy hh:mm a"); 
    String landing = arrivalDate.format(format); 
    System.out.printf("Arriving at : %s %n", landing); 
    } catch (DateTimeException ex) { 
    System.out.printf("%s can't be formatted!%n", arrivalDate); 
    ex.printStackTrace(); 
} 

Output : Arriving at : Jan 14 2014 04:33 PM

It can be seen that the current time is represented by the given "MMM dd yyyy hh:mm a" mode, which includes the month represented by three letters and the time represented by AM and PM.

Several key points of date and time API in Java 8

After reading these examples, I believe you have a certain understanding of the new time and date API in Java 8. Now let’s review some of the key elements of this new API.

  1. It provides javax.time.ZoneId to handle the time zone.

  2. It provides LocalDate and LocalTime classes

  3. All classes in the new time and date API in Java 8 are immutable and thread-safe. This is the opposite of the previous Date and Calendar API, where key classes like java.util.Date and SimpleDateFormat are all It is not thread safe.

  4. An important point in the new time and date API is that it clearly defines the basic time and date concepts, for example, instantaneous time, duration, date, time, time zone, and time period. They are all based on the ISO calendar system.

  5. Every Java developer should know at least these five classes in this new set of APIs: – Instant It represents the timestamp, such as 2014-01-14T02:20:13.592Z, which can be obtained from java.time.Clock Get it in the class, like this: Instant current = Clock.system(ZoneId.of("Asia/Tokyo")).instant(); – LocalDate It represents a date without time, such as 2014-01-14. It can be used to store birthdays, anniversaries, entry dates, etc. – LocalTime – It means the time without date – LocalDateTime – It contains time and date, but no offset with time zone – ZonedDateTime – This is a complete time with time zone, it is based on UTC/Greenwich Mean Time To adjust the time zone

  6. The main package of this library is java.time, which contains classes representing date, time, instant, and duration. It has two sub-packages, one is java.time.foramt, it is obvious what this is for, and the other is java.time.temporal, which can access various fields from a lower level.

  7. Time zone refers to areas on the earth that share the same standard time. Each time zone has a unique identifier, as well as a region/city (Asia/Tokyo) format and an offset time from Greenwich Mean Time. For example, the offset time in Tokyo is +09:00.

  8. The OffsetDateTime class actually contains LocalDateTime and ZoneOffset. It is used to represent a complete date (year, month, day) and time (hours, minutes, seconds, nanoseconds) including the offset from Greenwich Mean Time (+/- hours: minutes, such as +06:00 or -08:00) .

  9. The DateTimeFormatter class is used to format and parse dates in Java. Unlike SimpleDateFormat, it is immutable and thread-safe, and can be assigned to a static variable if needed. The DateTimeFormatter class provides many predefined formatters, and you can also customize the format you want. Of course, according to the convention, it also has a parse() method for converting a string into a date. If any error occurs during the conversion, it will throw a DateTimeParseException. Similarly, the DateFormatter class also has a format() method for formatting dates. If it fails, it will throw a DateTimeException.

  10. Another sentence, the two date formats of "MMM d yyyy" and "MMm dd yyyy" are also slightly different. The former can recognize the two strings "Jan 2 2014" and "Jan 14 2014", while the latter can be passed in If it is "Jan 2 2014", it will report an error because it expects two characters to be passed in the month. In order to solve this problem, when the day is a single digit, you have to add zeros in front, for example, "Jan 2 2014" should be changed to "Jan 02 2014".

That's all about Java 8 this new time and date API. These short examples are enough to understand some of the new classes in this new API. Since it is explained based on actual tasks, you don’t need to look around when you encounter time and date processing in Java later. We learned how to create and modify date instances. We also understand the difference between pure date, date plus time, date plus time zone, how to compare two dates, how to find a certain day to a specified date, such as the next birthday, anniversary or insurance date. We also learned how to parse and format dates in a thread-safe way in Java 8, without using thread-local variables or third-party libraries. The new API can handle any task related to time and date.

At last

Students who want to learn java can reply to the information by private message to receive a summary of the Java interview questions of the first-line manufacturers + Alibaba Taishan manual + learning and thinking guide for each knowledge point + a summary of Java core knowledge points in a 300-page pdf document!

The content of these materials are all the knowledge points that the interviewer must ask during the interview. The chapter includes many knowledge points, including basic knowledge, Java collections, JVM, multi-threaded concurrency, spring principles, microservices, Netty and RPC, Kafka , Diary, design pattern, Java algorithm, database, Zookeeper, distributed cache, data structure, etc. file

Guess you like

Origin blog.csdn.net/weixin_46577306/article/details/108189065