20 common usage examples of time and date libraries in Java 8

20 common usage examples of time and date libraries in Java 8

[[177393]]

In addition to lambda expressions, streams, and several minor improvements, Java 8 introduces a new set of date and time APIs. In this tutorial, we will learn how to use Java 8's APIs through a few simple task examples. Java's handling of dates, calendars, and times has always been criticized, especially its decision to define java.util.Date as mutable and SimpleDateFormat as non-thread-safe. It seems that Java has realized the need to provide better support for date and time functions, which is also good news for the community that is used to the Joda date and time library. The best thing about this new date and time library is that it clearly defines some date and time related concepts, such as instant, duration, date, time, time-zone, and period. It also borrows some of the advantages of the Joda library, such as separating the understanding of date and time for humans and machines. 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 a timestamp
  • LocalDate - a date that does not contain a specific time, such as 2014-01-14. It can be used to store birthdays, anniversaries, employment dates, etc.
  • LocalTime - It represents the time without date
  • LocalDateTime - It contains the date and time, but still no offset information or time zone.
  • ZonedDateTime - This is a complete date and time including the time zone, offset from UTC/Greenwich Mean Time.

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

How Java 8 handles time and date

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

Example 1 How to get today’s date in Java 8

Java 8 has a class called LocalDate, which can be used to represent today's date. This class is slightly different from java.util.Date because it only contains the date and no time. Therefore, if you only need to represent the date without the time, you can use it.

  1. LocalDate today = LocalDate.now(); System. out .println( "Today's Local date : " + today);
  2.   
  3. Output  
  4. Today's Local   date : 2014-01-14

You can see that it creates today's date without the time information. It also formats the date before printing it out, unlike the previous Date class, which prints out the data unformatted.

Example 2 How to get the current year, month and day in Java 8

The LocalDate class provides some very convenient methods for extracting the year, month, day and other date attributes. Using these methods, you can get any date attribute you need without having to use classes like java.util.Calendar:

  1. LocalDate today = LocalDate.now();
  2. int   year = today.getYear();
  3. int   month = today.getMonthValue();
  4. int   day = today.getDayOfMonth();
  5. System. out .printf( "Year : %d Month : %d day : %d \t %n" , year , month , day );
  6.   
  7. Output  
  8. Today's Local   date : 2014-01-14
  9. Year : 2014 Month : 1 day : 14

As you can see, getting the year and month information in Java 8 is very simple. You just need to use the corresponding getter method. You don't need to remember it. It is 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 another very useful factory method LocalDate.of() can create any date, which accepts year, month, and day parameters and returns an equivalent LocalDate instance. Another good thing about this method is that it does not make the mistakes of the previous API, for example, the year can only start from 1900, the month must start from 0, etc. The date here is what you write, for example, in the example below it represents January 14, there is no hidden logic.

  1. LocalDate dateOfBirth = LocalDate. of (2010, 01, 14);
  2. System. out .println( "Your Date of birth is : " + dateOfBirth);
  3.   
  4. Output : Your Date   of birth is : 2010-01-14

As you can see, the creation date is exactly what we wrote, January 14, 2014.

Example 4: How to check if two dates are equal in Java 8

When it comes to real-life tasks of dealing with time and dates, one common one is to check whether two dates are equal. You may often encounter the need to check whether today is a special day, such as a birthday, anniversary, or holiday. Sometimes, you will be given a date and asked to check whether it is a special day such as a holiday. The following example will help you complete such tasks in Java 8. As you might expect, LocalDate overrides the equals method to compare dates, as shown below:

  1. LocalDate date1 = LocalDate. of (2014, 01, 14); if(date1.equals(today)){
  2. System. out .printf( "Today %s and date1 %s are same date %n" , today, date1);
  3. }
  4.   
  5. Output  
  6. today 2014-01-14 and date1 2014-01-14 are same date  

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

Example 5: How to check for recurring events, such as birthdays, in Java 8

Another practical task related to date and time in Java is to check for recurring events, such as monthly billing day, wedding anniversary, monthly payment date or annual insurance payment date. If you work in an e-commerce company, there must be a module that sends birthday wishes to users and sends them greetings on every important holiday, such as Christmas, Thanksgiving, and Deepawali in India. How to check whether it is a holiday or a recurring event in Java? Use the MonthDay class. This class is a combination of month and day, without year information, which means you can use it to represent some days that repeat every year. Of course, there are other combinations, such as the YearMonth class. It is immutable and thread-safe like other classes in the new date and time library, and it is also a value class. Let's take an example to see how to use MonthDay to check for a recurring date:

  1. LocalDate dateOfBirth = LocalDate. of (2010, 01, 14);
  2. MonthDay birthday = MonthDay. of (dateOfBirth.getMonth(), dateOfBirth.getDayOfMonth());
  3. MonthDay currentMonthDay = MonthDay. from (today);
  4. if(currentMonthDay.equals(birthday)){
  5. System. out .println( "Many Many happy returns of the day !!" );
  6. } else {
  7. System. out .println( "Sorry, today is not your birthday" );
  8. }
  9.   
  10. Output : Many Many happy returns   of the day !!

Although the year is different, today is your 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 the first example where we got the current date. 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 this to how you got the current time before Java 8.

  1. LocalTime time = LocalTime.now(); System. out .println( "local time now : " + time );
  2.   
  3. Output  
  4. local   time now : 16:33:33.369 // in   hour , minutes, seconds, nano seconds

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

Example 7 How to add hours to a 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, don't forget to store this new reference.

  1. LocalTime time = LocalTime.now();
  2. LocalTime newTime = time .plusHours(2); // adding two hours
  3. System. out .println( "Time after 2 hours : " + newTime);
  4.   
  5. Output :
  6. Time   after 2 hours : 18:33:33.369

You can see that the current time is 16:33:33.369 after 2 hours. Now you can compare it with the old way of adding or subtracting hours in Java. You can see which one is better at a glance.

Example 8 How to get the date one 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.

  1. LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS);
  2. System. out .println( "Today is : " + today);
  3. System. out .println( "Date after 1 week : " + nextWeek);
  4.   
  5. Output :
  6. Today is : 2014-01-14
  7. Date   after 1 week: 2014-01-21

You can see what the date will be 7 days later, which is a week later. You can use this method to add a month, a year, an hour, a minute, or even a decade. Check out the ChronoUnit class in the Java API for more options.

Example 9: Dates before and after one year

This is a sequel to the previous example. In the previous example, we learned how to use the plus() method of LocalDate to add days, weeks or months to a date. Now let's learn how to use the minus() method to find out the day one year ago.

  1. LocalDate previousYear = today.minus(1, ChronoUnit.YEARS);
  2. System. out .println( "Date before 1 year : " + previousYear);
  3. LocalDate nextYear = today.plus(1, YEARS);
  4. System. out .println( "Date after 1 year : " + nextYear);
  5.   
  6. Output :
  7. Date before 1 year : 2013-01-14
  8. Date   after 1 year : 2015-01-14

We can see that there are two years in total, one is 2013 and the other is 2015, which are the year before and after 2014 respectively.

Example 10 Using Clock in Java 8

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

  1. // Returns the current   time based on your system clock and   set   to UTC.
  2. Clock clock = Clock.systemUTC();
  3. System. out .println( "Clock : " + clock);
  4.   
  5. // Returns   time based on system clock zone Clock defaultClock =
  6. Clock.systemDefaultZone();
  7. System. out .println( "Clock : " + clock);
  8.   
  9. Output :
  10. Clock : SystemClock[Z]
  11. Clock : SystemClock[Z]

You can compare a specific date to this clock, like this:

  1. public class MyClass {
  2. private Clock clock; // dependency inject ...
  3.   
  4. public void process(LocalDate eventDate) {
  5.   
  6. if(eventDate.isBefore(LocalDate.now(clock)) {
  7. ...
  8. }
  9. }
  10. }

This is very handy if you need to deal with dates in different time zones.

Example 11 How to determine whether a date is before or after another date in Java

This is also a common task in real projects. How do you determine whether a date is before or after another date, or is exactly equal? ​​In Java 8, the LocalDate class has an isBefore() and isAfter() method that can be used to compare two dates. If the date that calls the method is earlier than the given date, the isBefore() method will return true.

  1. LocalDate tomorrow = LocalDate. of (2014, 1, 15); , if(tommorow.isAfter(today)){
  2. System. out .println( "Tomorrow comes after today" );
  3. }
  4. LocalDate yesterday = today.minus(1, DAYS);
  5. if(yesterday.isBefore(today)){
  6. System. out .println( "Yesterday is day before today" );
  7. }
  8.   
  9. Output :
  10. Tomorrow comes after today
  11. Yesterday is   day before today

As you can see, it is very easy to compare dates in Java 8. There is no need to use another class like Calendar to accomplish such a task.

Example 12: Handling different time zones in Java 8

Java 8 not only separates date and time, but also time zones. There are several groups of classes related to time zones, such as ZoneId, which represents a specific time zone, and ZonedDateTime, which represents a 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:

  1. // Date   and   time   with timezone in Java 8 ZoneId america = ZoneId. of ( "America/New_York" );
  2. LocalDateTime localtDateAndTime = LocalDateTime.now();
  3. ZonedDateTime dateAndTimeInNewYork = ZonedDateTime. of (localtDateAndTime, america );
  4. System. out .println( "Current date and time in a particular timezone : " + dateAndTimeInNewYork);
  5.   
  6. Output :
  7. Current   date   and   time   in a particular timezone : 2014-01-14T16:33:33.373-05:00[America/New_York]

Compare this to the way we converted local time to GMT. By the way, just like before Java 8, make sure you don’t get the timezone text wrong, or you’ll get an exception like this:

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

Example 13: How to represent a fixed date, such as a credit card expiration date

Just as MonthDay represents a recurring day, YearMonth is another combination that represents dates such as credit card payment dates, time deposit due dates, and options expiration dates. You can use this class to find out how many days there are in a month. The lengthOfMonth() method returns the number of days in this YearMonth instance, which is very useful for checking whether February has 28 or 29 days.

  1. YearMonth currentYearMonth = YearMonth.now(); System. out .printf( "Days in month year %s: %d%n" , currentYearMonth, currentYearMonth.lengthOfMonth());
  2. YearMonth creditCardExpiry = YearMonth. of (2018, Month .FEBRUARY);
  3. System. out .printf( "Your credit card expires on %s %n" , creditCardExpiry);
  4.   
  5. Output :
  6. Days in   month   year 2014-01: 31
  7. Your credit card expires on 2018-02

Example 14: How to Check Leap Year in Java 8

This is not complicated. The LocalDate class has an isLeapYear() method that returns whether the year corresponding to the current LocalDate is a leap year. If you still want to reinvent the wheel, you can take a look at this code, which is written in pure Java to determine whether a certain year is a leap year.

  1. if (today.isLeapYear()) {
  2. System. out .println( "This year is Leap year" );
  3. } else {
  4. System. out .println( "2014 is not a Leap year" );
  5. }
  6.   
  7. Output : 2014 is   not a leap year  

You can check a few more years to see if the result is correct. It is better to write a unit test to test it for normal years and leap years.

Example 15 How many days and months are included between two dates

Another common task is to calculate the number of days, weeks, or years between two given dates. You can use the java.time.Period class to accomplish this. In the following example, we will calculate the number of months between the current date and a future date.

  1. LocalDate java8Release = LocalDate. of (2014, Month .MARCH, 14);
  2. Period periodToNextJavaRelease =
  3. Period. between (today, java8Release);
  4. System. out .println( "Months left between today and Java 8 release : " + periodToNextJavaRelease.getMonths() );
  5.   
  6. Output :
  7. 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 is a gap of 2 months in between.

Example 16: Date and time with time zone offset

In Java 8, you can use the ZoneOffset class to represent a time zone, such as India is GMT or UTC5:30, and you can use its static method ZoneOffset.of() to get the corresponding time zone. Once you get the offset, you can create an OffsetDateTime with LocalDateTime and the offset.

  1. LocalDateTime datetime = LocalDateTime. of (2014, Month .JANUARY, 14, 19, 30);
  2. ZoneOffset offset = ZoneOffset. of ( "+05:30" );
  3. OffsetDateTime date = OffsetDateTime. of (datetime, offset);
  4. System. out .println( "Date and Time with timezone offset in Java : " + date );
  5.   
  6. Output :
  7. Date   and   Time   with timezone offset in Java : 2014-01-14T19:30+05:30

You can see that the date and time are now 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, it is now a piece of cake. The Instant class has a static factory method now() that returns the current timestamp, as follows:

  1. Instant timestamp = Instant.now();
  2. System. out .println( "What is value of this instant " + timestamp );
  3.   
  4. Output :
  5. What is value of this instant 2014-01-14T08:33:33.379Z

As you can see, the current timestamp contains date and time, which is very similar to java.util.Date. In fact, Instant is Date before Java 8. You can use the methods in these two classes to convert 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 predefined formatters to parse/format dates in Java 8

Before Java 8, formatting dates and times was a technical job. Our good friend SimpleDateFormat was not thread-safe, and it was a bit cumbersome if used as a local variable for formatting. Thanks to thread local variables, it can be used in a multi-threaded environment, but Java has been in 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 use the predefined BASICISODATE format, which will format February 14, 2014 into 20140114.

  1. String dayAfterTommorrow = "20140116" ;
  2. LocalDate formatted = LocalDate.parse(dayAfterTommorrow,
  3. DateTimeFormatter.BASIC_ISO_DATE);
  4. System. out .printf( "Date generated from String %s is %s %n" , dayAfterTommorrow, formatted);
  5.   
  6. Output :
  7. 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 a date in Java

In the above example, we used the built-in date and time formatter to parse the date string. Of course, predefined formatters are 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 following example is "MMM dd yyyy". You can pass any pattern to the ofPattern static method () of DateTimeFormatter, and it will return an instance. The literal value of this pattern is the same as in the previous example. For example, M still represents month, and m is still minute. Invalid patterns will throw a DateTimeParseException exception, but if it is a logical error, such as using m when it should be used, there is nothing you can do.

  1. String goodFriday = "Apr 18 2014" ;
  2. try {
  3. DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MMM dd yyyy" );
  4. LocalDate holiday = LocalDate.parse(goodFriday, formatter);
  5. System. out .printf( "Successfully parsed String %s, date is %s%n" , goodFriday, holiday);
  6. } catch (DateTimeParseException ex) {
  7. System. out .printf( "%s is not parsable!%n" , goodFriday);
  8. ex.printStackTrace();
  9. }
  10.   
  11. Output :
  12. Successfully parsed String Apr 18 2014, date   is 2014-04-18

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

Example 20 How to format a date and convert it into a string in Java 8

In the previous two examples, although we used the DateTimeFormatter class, we mainly parsed date strings. In this example, we are going to do the opposite. Here we have an instance of the LocalDateTime class, and we want to convert it into a formatted date string. This is by far the simplest and most convenient way to convert a date to a string in Java. The following example will return a formatted string. Similar to the previous example, we still need to create an instance of the DateTimeFormatter class with the specified pattern string, but we call the format() method instead of the parse method of the LocalDate class. This method returns a string representing the current date, and the corresponding pattern is defined in the passed DateTimeFormatter instance.

  1. LocalDateTime arrivalDate = LocalDateTime.now();
  2. try {
  3. DateTimeFormatter format = DateTimeFormatter.ofPattern( "MMM dd yyyy hh:mm a" );
  4. String landing = arrivalDate.format(format);
  5. System. out .printf( "Arriving at : %s %n" , landing);
  6. } catch (DateTimeException ex) {
  7. System. out .printf( "%s can't be formatted!%n" , arrivalDate);
  8. ex.printStackTrace();
  9. }
  10.   
  11. Output : Arriving at : Jan 14 2014 04:33 PM

As you can see, the current time is represented by the given "MMM dd yyyy hh:mm a" pattern, which contains the three-letter month and the time expressed in AM and PM.

Several key points of the 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 key elements of this new API.

  1. It provides javax.time.ZoneId for handling time zones.
  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, which is exactly the opposite of the previous Date and Calendar API, where key classes like java.util.Date and SimpleDateFormat were not thread-safe.
  4. An important point in the new time and date API is that it clearly defines the basic concepts of time and date, such as instant time, duration, date, time, time zone and time period. They are all based on the ISO calendar system.
  5. Every Java developer should be aware of at least five classes in this new API:
    1. Instant represents a timestamp, such as 2014-01-14T02:20:13.592Z, which can be obtained from the java.time.Clock class, like this: Instant current = Clock.system(ZoneId.of("Asia/Tokyo")).instant();
    2. LocalDate represents a date without time, such as 2014-01-14. It can be used to store birthdays, anniversaries, employment dates, etc.
    3. LocalTime – It represents the time without the date
    4. LocalDateTime – It contains the time and date, but without the offset with time zone
    5. ZonedDateTime – This is a complete date and time with time zone adjustment based on UTC/Greenwich Mean Time
  6. The main package of this library is java.time, which contains classes representing dates, times, instants, and durations. It has two subpackages, one is java.time.format, which is obvious what it is used for, and the other is java.time.temporal, which can access individual fields from a lower level.
  7. A time zone is an area of ​​the Earth that shares the same standard time. Each time zone has a unique identifier, a region/city format (Asia/Tokyo) and an offset from Greenwich Mean Time. For example, Tokyo's offset is +09:00.
  8. The OffsetDateTime class actually includes LocalDateTime and ZoneOffset. It is used to represent a complete date (year, month, day) and time (hour, minute, second, nanosecond) including the Greenwich Mean Time offset (+/- 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 necessary. The DateTimeFormatter class provides many predefined formatters, and you can also customize the format you want. Of course, by convention, it also has a parse() method for converting strings into dates. If any errors occur during the conversion, it will throw a DateTimeParseException. Similarly, the DateFormatter class also has a format() method for formatting dates, which will throw a DateTimeException if an error occurs.
  10. By the way, the date formats "MMM d yyyy" and "MMm dd yyyy" are slightly different. The former can recognize "Jan 2 2014" and "Jan 14 2014", while the latter will report an error if "Jan 2 2014" is passed in, because it expects two characters for the month. To solve this problem, you have to add 0 in front when the day is a single digit, for example, "Jan 2 2014" should be changed to "Jan 02 2014".

That's it for the new date and time API in Java 8. These few short examples are enough to understand some of the new classes in this new API. Since it is based on real-life tasks, you don't have to look around when you encounter time and date processing in Java in the future. We learned how to create and modify date instances. We also learned the difference between a pure date, a date with a time, and a date with a time zone, how to compare two dates, and how to find the number of days from a certain date to a specified date, such as the next birthday, anniversary, or insurance date. We also learned how to parse and format dates in Java 8 in a thread-safe way without the need to use thread-local variables or third-party libraries. The new API is capable of any task related to time and date.

<<:  Android immersive status bar and suspension effect

>>:  Writing a JavaScript framework: better timed execution than setTimeout

Recommend

WeX5 cross-terminal mobile development framework V3.2 official version released

WeX5 Enterprise Rapid Development Platform V3.2 O...

Carbon, how to "leverage" the wonderful world?

Carbon, a seemingly ordinary element, is one of t...

Memory price hikes bring huge profits, but Samsung's position is not secure

Electronic product enthusiasts have been a bit de...

When is the healthiest time to eat apples? What does the research say?

Apple is a fruit known for its health benefits, a...