Java 8 Date and time API: the Instant class

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 Instant class. It represents a point of time in a continuous timeline where this time point is accurate to the level of nanoseconds.

The immutable Instant class comes with some default built-in values:

Read more of this post

Advertisement

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.

Read more of this post

Java 8 Date and time API: the Instant class

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 Instant class. It represents a point of time in a continuous timeline where this time point is accurate to the level of nanoseconds.

The immutable Instant class comes with some default built-in values:

Instant now = Instant.now();
Instant unixEpoch = Instant.EPOCH;
Instant minimumInstant = Instant.MIN;
Instant maximumInstant = Instant.MAX;
  • “now”, as the name suggests, represent the current date, or current instance of time in the UTC time zone.
  • “unixEpoch” will be the traditional UNIX epoch date from 1970 January 1 midnight. This is also an important point of reference of the timeline of the Instant class. E.g. the date 2014-01-01 will have a positive number as the “seconds since EPOCH” whereas 1960-01-01 will get a negative value for the same property.
  • The minimum value of the Instant class is exactly 1 billion years ago, denoted as ‘-1000000000-01-01T00:00Z’ in the documentation. This is the starting point of the timeline of the Instant class
  • The maximum value is consequently the last moment of the year of 1 billion. This is the end point of the timeline of the Instant class

Example

Suppose you’d like to measure the time it takes to run a method:

Instant start = Instant.now();
Thread.sleep(10000);
Instant end = Instant.now();
Duration duration = Duration.between(start, end);
long seconds = duration.getSeconds();

There we see yet another new object from the java.time package, namely Duration. The Duration object allows to easily retrieve the time span between two dates and retrieve the days, hours, seconds etc. of that time span. In this case “seconds” will be equal to 10 as expected.

Note, however, that the Instant class cannot be used for date purposes such as February 23 2013. There’s no concept of years, months and days in the Instant class like we have in Date and Calendar in Java 7. If you’re looking to handle dates then LocalDate, LocalDateTime and LocalTime classes will be more useful. Check out the the link at the end of this post to find the posts on these and various other date-related classes in Java 8.

Duration

The Duration class has a number of useful methods. Duration is very similar to the Period class we saw in the post referenced in the previous paragraph. Here come some examples.

Duration.between

Suppose you have two Duration classes and you’d like to see which one was longer. The “compareTo” method will help you:

Instant startOne = Instant.now();
Thread.sleep(1000);
Instant endOne = Instant.now();
Duration durationOne = Duration.between(startOne, endOne);

Instant startTwo = Instant.now();
Thread.sleep(100);
Instant endTwo = Instant.now();
Duration durationTwo = Duration.between(startTwo, endTwo);
    
int compareTo = durationOne.compareTo(durationTwo);

compareTo will be 1 in the above example as the first part of the comparison, i.e. durationOne is longer. It will be -1 if comparisonTwo is longer and 0 if they are of equal length.

divideBy

You can also divide a duration by a value to see how many sections of that value fit into a duration:

Duration dividedBy = durationOne.dividedBy(10);
long toMillis = dividedBy.toMillis();

Here we want to divide durationOne, i.e. 100 millis by 10 millis. The variable “dividedBy” will almost always get the value 10 as 100 / 10 = 10 but the exact timing can depend on the code execution when “startOne” and “startTwo” are created, so you might see 11 sometimes.

isZero

This is to check if two instances happened at the same time, i.e. there’s no duration between them:

Duration zeroDuration = Duration.between(startOne, startOne);
boolean zero = zeroDuration.isZero();

“zero” will be true in this case.

isNegative

isNegative will occur if the end date occurred before the start date. I’m not sure how that scenario can occur but let’s deliberately supply the wrong values to the between method:

Duration negativeDuration = Duration.between(endOne, startOne);
boolean negative = negativeDuration.isNegative();

“negative” will be true.

Plus and minus methods

You’ll find a range of methods whose names start with “plus” and “minus”. They are meant to add and subtract time units to and from a Duration instance. Examples:

Duration minusMinutes = durationOne.minusMinutes(10);
Duration plusDays = durationOne.plusDays(2);
Duration plus = durationOne.plus(durationTwo);

Read the next post on Java 8 Dates here.

View all posts related to Java here.

Java 8 Date and time API: the LocalDateTime class

Introduction

In this post we saw how to represent dates on the level of days, such as 2014-10-05 using the LocalDate class. This post discussed the usage of LocalTime to show the point of time within the 24-hr clock, such as 11:45:43.

LocalDate has no concept of time units below the day level. LocalTime has no concept of time above the level of hours. However, what if you need to represent the date as 2014-10-05 11:45:43, i.e. with both the day and time sections? You can turn to the aptly named LocalDateTime class which marries LocalTime and LocalDate.

The usage of LocalDateTime is very similar to both LocalDate and LocalTime. You can quickly read through the posts referenced above for further information. Most date-related methods are common for LocalDate, LocalTime and LocalDateTime.

LocalDateTime

You can get the current local date-time as follows:

LocalDateTime now = LocalDateTime.now();

This will get the current date according to the default time zone of your computer.

You can construct a new LocalDateTime instance using the various static “of” methods, e.g.

LocalDateTime someDateInPast = LocalDateTime.of(2014, Month.MAY, 23, 10, 23, 43);

You can add/subtract some units of time using the “plus” and “minus” methods. The “until” method will find the time span between the two time points in the provided unit of measurement:

LocalDateTime later = now.plusMinutes(321);
long until = now.until(later, ChronoUnit.MINUTES);

“until” will be 321 minutes as expected.

We saw that in the case of LocalDate and LocalTime not all enumeration types of ChronoUnit are supported which is due to the allowed level of granularity. LocalDateTime allows for all values in the enumeration, from nanoseconds to eras – defined as 1 billion years in Java 8, i.e. you can measure the difference between two LocalDateTime instances in terms of nanoseconds ranging to eras – as long as the “long” type supports them which might not be the case with nanoseconds given a large enough time range.

The isAfter and isBefore methods work as the method names imply:

LocalDateTime now = LocalDateTime.now();
LocalDateTime someDateInPast = LocalDateTime.of(2014, Month.MAY, 23, 10, 23, 43);
boolean before = now.isBefore(later);
boolean after = now.isAfter(later);

“before” will be true and “after” will be false as expected.

You can extract the LocalDate and LocalTime portions of LocalDateTime using the toLocalDate and toLocalTime methods:

LocalDate toLocalDate = now.toLocalDate();
LocalTime toLocalTime = now.toLocalTime();

You can extract the various portions of the LocalDateTime instance using the various “get” methods, such as:

LocalDateTime someDateInPast = LocalDateTime.of(2014, Month.MAY, 23, 10, 23, 43);
DayOfWeek dayOfWeek = someDateInPast.getDayOfWeek();
int dayOfYear = someDateInPast.getDayOfYear();
int year = someDateInPast.getYear();

The returned values are “FRIDAY”, 143 – i.e. the date in someDateInPast was the 143rd day in the year of 2014 -, and 2014 respectively.

View all posts related to Java here.

Java 8 Date and time API: the LocalTime class

Introduction

In this post we saw how to handle local date values to the level of days with the LocalDate object. A typical point in time handled through this object is e.g. 2014-03-02. There’s no concept of hours and minutes in that object.

LocalTime

The “time of day” equivalent of LocalDate is LocalTime and its usage is very similar. I recommend you read through the post referenced above as many methods, like the “plus” and “minus” ones still apply in the same form. LocalTime will have no concept of days, months and years. You can use this class if e.g. some of your logic depends on the time of day every day, regardless of the calendar day.

Here’s how you can find the current time of day:

LocalTime now = LocalTime.now();

This will find the current time in the default time zone of your computer.

You can also create a time using the “of” static method. You’ll set the time to 5:32am as follows:

LocalTime early = LocalTime.of(5, 32);

You can add/subtract some units of time using the “plus” and “minus” methods. The “until” method will find the difference between the two time points in the provided unit of measurement:

LocalTime now = LocalTime.now();
LocalTime later = now.plusHours(2);
long until = now.until(later, ChronoUnit.MINUTES);

“until” will be 120 as there are 120 minutes from “now” until “now + 2 hrs” of course. However, if you run this code at e.g. 23:30 in your time zone then “until” will be a negative value as 23:30 plus 2 hrs is 01:30. There’s no “next day” in LocalTime so “until” in that case will be -1320 which is the same as -22 hrs.

Only those ChronoUnit enumerations are valid that make sense for the LocalTime class: Minutes, hours, seconds, etc., anything under the level of days. If you’re not sure then you can check if the ChronoUnit is supported using the isSupported method:

boolean supported = now.isSupported(ChronoUnit.CENTURIES);

The above code will yield “false”.

The isAfter and isBefore methods work as the method names imply:

LocalTime now = LocalTime.now();
LocalTime later = now.plusMinutes(10);
boolean before = now.isBefore(later);
boolean after = now.isAfter(later);

However, be careful with the return values. Just like above, it depends on when during the day you run this code so don’t assume that “before” will always be true and “after” will always be false in the above example. If you run this code at 23:58 then the return values will be the exact opposite as 23:58 + 10 minutes = 00:08 which will be before 23:58 and 23:58 comes after 00:08.

You can use the overridden “compareTo” method in a similar manner – it will return -1, 0 or 1 depending on which side of the comparison comes first – but again the result will depend on the exact timing.

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

View all posts related to Java here.

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.

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: