Friday, September 29, 2017

Java 8 Date And Time API: LocalDate

With Java 8 Oracle introduced new Date and Time APIs which address the shortcomings of the existing java.util.Date and java.util.Calendar. In this article we will take a look at the Java 8 Date and Time API with few examples of the new LocalDate class introduced by Java 8.

Improvements to Existing Calendar and Date Classes

Thread Safety: The existing API was not designed with concurrency in mind. This meant developers had to come up with custom solutions to handle thread safety. The Java 8 Date/Time API ensures thread safety by making all the new classes immutable. Domain-driven design: The Java 8 date/time API has clear domain boundaries, and defines classes with specific use cases. Support for non-standard Calendars: The Java 8 Date/Time API provides support for non-standard calendaring systems (Japanese calendar for example) without affecting the standard calendar implementation.

LocalDate

The LocalDate represents a date in yyyy-mm-dd format. Unlike it's predecessor Date, LocalDate does not store the time. The following few examples show how you can use the java.time.LocalDate class
  • Create an instance of LocalDate for today: The LocalDate.now() method can be used to obtain an instance of LocalDate representing the current date.
    LocalDate localDate = LocalDate.now();
  • Create an instance of LocalDate for any specific date: There are a couple of ways in which you can obtain an instance of LocalDate representing a specific date
    • The LocalDate.of() method takes the year, month, and day as arguments in that order. All are integer values
      LocalDate specificDate1 = LocalDate.of(2017, 1, 1);
    • The LocalDate.parse() method again has a couple of options, the first one takes in the default format (yyyy-MM-dd) as input and tries to parse it. In the second variation, you can pass the java.time.format.DateTimeFormatter specifying the format in which you expect the date.
        LocalDate specificDate2 = LocalDate.parse("2017-01-01"); //2017-1-1 will fail as the default format is expected to be yyyy-mm-dd
      System.out.println(specificDate2);
      DateTimeFormatter dateTimeFormat = DateTimeFormatter.ofPattern("MM-dd-yyyy");
      LocalDate specificDate3 = LocalDate.parse("12-01-2017", dateTimeFormat);
      System.out.println(specificDate3);
  • Add or Subtract with LocalDate: LocalDate class provides utility methods to add or subtract days/months/years (represented by java.time.temporal.TemporalUnit interface). The following examples illustrate the use of Date arithmetic on LocalDate.
    LocalDate localDate = LocalDate.now();
    
    // Subtract Days
    System.out.println("3 days before today is : " + localDate.minus(3, ChronoUnit.DAYS));
    
    // Subtract Decades
    System.out.println("3 decades before today is : " + localDate.minus(3, ChronoUnit.DECADES));
    
    // Add Days
    System.out.println("3 days after today is : " + localDate.plus(3, ChronoUnit.DAYS));
    
    // Add Decades
    System.out.println("3 decades after today is : " + localDate.plus(3, ChronoUnit.DECADES));
  • Get parts of the date: LocalDate also provides a few utility methods to extract part of the date and get more information about the date, like the day of the week, day of the year etc.
    // Day of the Week
    System.out.println("The day of the week is : " + localDate.getDayOfWeek());
    
    // Day of the year
    System.out.println("The day of the year is : " + localDate.getDayOfYear());
    
    System.out.println("Is this a Leap Year? " + localDate.isLeapYear());
  • Compare two LocalDates: The isBefore, isAfter, and isEqual methods offer a way to compare two LocalDate objects
    System.out.println("Is today after 2017-12-12? " + localDate.isAfter(LocalDate.parse("2017-12-12")));
    
    System.out.println("Is today after 2017-12-12? " + localDate.isBefore(LocalDate.parse("2017-12-12")));
    
    System.out.println("Is today 2017-12-12? " + localDate.isEqual(LocalDate.parse("2017-12-12")));
  • Days between two Dates: The until() method provides a couple variants that can be used to calculate the number of days/months/yearts etc between two LocalDates. The first variant takes just one parameter (the endDate), and calculates the Period between the start and end dates, the Period will shows the number of years, months and days between the start and end dates. The second variation takes in the TemporalUnit as a parameter, and can be used to calculate the number Months, Years etc. between the start date and end date.
    // Period between two dates
    System.out.println("Number of days from now to 2017-12-12: " + localDate.until(LocalDate.parse("2017-12-12")));  //Variant 1: Will print something like P2M10D, which is short for 2months and 10 days.
    
    // Days between two dates
    System.out.println("Number of days from now to 2017-12-12: " + localDate.until(LocalDate.parse("2017-12-12"), ChronoUnit.DAYS));
    
    // Months between two dates
    System.out.println("Number of days from now to 2017-12-12: " + localDate.until(LocalDate.parse("2017-12-12"), ChronoUnit.MONTHS));
  • Date Boundaries: The with() method can be used to identify the first of the month/year etc. of a given LocalDate. The with() method takes a TemporalAdjuster as a parameter as shown below.
    // First day of this month
    System.out.println("First day of this month is : " + localDate.with(TemporalAdjusters.firstDayOfMonth()));
    
    // First day of next month
    System.out.println("First day of next month is : " + localDate.with(TemporalAdjusters.firstDayOfNextMonth()));
    
    // Last day of this month
    System.out.println("Last day of this month is : " + localDate.with(TemporalAdjusters.lastDayOfMonth()));

Full Code

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;

public class LocalDateExamples {

 public static void main(String[] args) {
  LocalDate specificDate1 = LocalDate.of(2017, 1, 1);
  System.out.println(specificDate1);

  LocalDate specificDate2 = LocalDate.parse("2017-01-01"); // 2017-1-1 will fail as the default format is expected to be yyyy-MM-dd
  System.out.println(specificDate2);

  DateTimeFormatter dateTimeFormat = DateTimeFormatter.ofPattern("MM-dd-yyyy");
  LocalDate specificDate3 = LocalDate.parse("12-01-2017", dateTimeFormat);
  System.out.println(specificDate3);

  LocalDate localDate = LocalDate.now();

  System.out.println("3 days before today is : " + localDate.minus(3, ChronoUnit.DAYS));
  System.out.println("3 decades before today is : " + localDate.minus(3, ChronoUnit.DECADES));
  System.out.println("3 days after today is : " + localDate.plus(3, ChronoUnit.DAYS));
  System.out.println("3 decades after today is : " + localDate.plus(3, ChronoUnit.DECADES));

  System.out.println("The day of the week is : " + localDate.getDayOfWeek());
  System.out.println("The day of the year is : " + localDate.getDayOfYear());
  System.out.println("Is this a Leap Year? " + localDate.isLeapYear());

  System.out.println("Is today after 2017-12-12? " + localDate.isAfter(LocalDate.parse("2017-12-12")));
  System.out.println("Is today after 2017-12-12? " + localDate.isBefore(LocalDate.parse("2017-12-12")));
  System.out.println("Is today 2017-12-12? " + localDate.isEqual(LocalDate.parse("2017-12-12")));

  System.out.println("Number of days from now to 2017-12-12: " + localDate.until(LocalDate.parse("2017-12-12"), ChronoUnit.DAYS));
  System.out.println("Number of days from now to 2017-12-12: " + localDate.until(LocalDate.parse("2017-12-12")));
  System.out.println("Number of days from now to 2017-12-12: " + localDate.until(LocalDate.parse("2017-12-12"), ChronoUnit.MONTHS));

  System.out.println("First day of this month is : " + localDate.with(TemporalAdjusters.firstDayOfMonth()));
  System.out.println("First day of next month is : " + localDate.with(TemporalAdjusters.firstDayOfNextMonth()));
  System.out.println("Last day of this month is : " + localDate.with(TemporalAdjusters.lastDayOfMonth()));
 }
}

No comments:

Post a Comment

Popular Posts