Java 8 Date and time API: the LocalDate class

Introduction

The Date and time API in Java 8 has been completely revamped. Handling dates, time zones, calendars etc. had been cumbersome and fragmented in Java 7 with a lot of deprecated methods. Developers often had to turn to 3rd party date handlers for Java such as Joda time.

One of many new key concepts in the java.time package of Java 8 is the immutable LocalDate class. A LocalDate represents a date at the level of days such as April 04 1988.

LocalDate

You can easily get hold of the current date of the default time zone of the local computer – in my case it’s CET:

LocalDate localDate = LocalDate.now();

…or you can construct a date using the static “of” method:

LocalDate someDayInApril = LocalDate.of(1988, Month.APRIL, 4);

LocalDate comes with the following constants:

  • LocalDate.MAX: ranges until year-month-day of ‘+999999999-12-31’
  • LocalDate.MIN: reaches as far back as years-months-days ‘-999999999-01-01’

Period

The Period class is strongly related to LocalDate. You can find the time span between two LocalDate instances using the “until” method which returns a Period object:

Period timeSpan = someDayInApril.until(localDate);
int years = timeSpan.getYears();
int months = timeSpan.getMonths();
int days = timeSpan.getDays();

At the time of writing this post there were 26 years, 6 months and 27 days between the two dates.

The Period class has a static “between” method to achieve the same:

Period between = Period.between(someDayInApril, localDate);

…which yields the same time difference as the “until” method above.

Normalisation

A period can be normalised so that values like 13 months can be changed to 1 year and 1 month instead. Let’s create a 23-month period and normalise it:

Period ofMonths = Period.ofMonths(23);
Period normalized = ofMonths.normalized();

“normalized” will have 1 year and 11 months for the getYears and getMonths values respectively. “ofMonth” would have 0 years and 23 months instead.

Let’s test this with days:

Period ofDays = Period.ofDays(4322);
Period daysNormalised = ofDays.normalized();

In this case, however, both will yield getDays = 4322, years and months will be 0. This is expected as the number of days in a month can vary so the calculation would be based on some average, like 30 days at best but that result would almost certainly be incorrect. The previous example succeeded as the number of months in a year is set.

Zero period

The isZero() method of Period returns true if we compare two periods and they refer to the same date:

Period zeroPeriod = someDayInApril.until(someDayInApril);
boolean zero = zeroPeriod.isZero();

…zero will be “true”.

Negative period

Negative periods occur if we compare two LocalDate instances and take the later date as point of reference in the comparison:

Period negativePeriod = localDate.until(someDayInApril);
boolean negative = negativePeriod.isNegative();

“negative” will be true. The year, month and day values will be -26, -6 and -27.

You can easily transform that into a positive period though:

Period negated = negativePeriod.negated();

The year, month and day values of “negated” will be 26, 6 and 27.

Multiplication

You can multiply a Period with an integer which will multiply the year, month and day values with that integer without normalising the date. So in case you need to get a twice as long period you can do as follows:

Period twiceAsLong = ofDays.multipliedBy(2);

Plus and minus methods

Both the LocalDate and the Period classes have methods whose names start with “plus” or “minus” which serve to add or subtract a certain amount of time to and from a date/period. Examples:

LocalDate plusDays = localDate.plusDays(20);
LocalDate minusYears = localDate.minusYears(15);
Period minusMonths = between.minusMonths(11);

You can probably guess what these operations do.

Total number of time units

What if you’d like to know the total number of days between two LocalDate instances? The “until” method has an overload that you can use. E.g. here’s how you find the total number of days between “localDate” and “someDayInApril”:

long until = someDayInApril.until(localDate, ChronoUnit.DAYS);

…which at this time gives 9706 days. The ChronoUnit enumeration in the java.time.temporal package has other values to find the total number of “x” between two local dates but not all of them are supported in the “until” operation. E.g. you cannot calculate the number of hours or nanoseconds between two LocalDate instances. Any level of detail more fine grained than DAYS will throw an exception of type java.time.temporal.UnsupportedTemporalTypeException as LocalDate is only available at the day level: there’s no concept of hours, minutes etc. in the case of LocalDate.

In the next post we’ll look at the LocalTime class.

View all posts related to Java here.

Advertisement

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

Bite-size insight on Cyber Security for the not too technical.

%d bloggers like this: