Core Java

OCA Java 8 Preparation : Period

In continuation of this post covering the temporal classes – LocalDate, LocalTime and LocalDateTime, today we’ll be covering the Period class which is also on the OCA Java 8 Exam.

Creating Period instances :

Period class also belongs to java.time package. It represents a date-based amount of time in terms of years, months, and days eg : ‘P2Y4M8D‘ signifies 2 years, 4 months and 8 days.Much like all other temporal classes, it is immutable and hence thread-safe. It also exposes static of() method for instantiating its objects along with some other available options.The values can be positive or negative.

static Period of(int years, int months, int days)
static Period ofYears(int years)
static Period ofMonths(int months)
static Period ofWeeks(int weeks)
static Period ofDays(int days)

//Example usage of above methods :
Period p = Period.of(3, 5, 12);
System.out.println(p);//P3Y5M12D- represents 3yrs, 5months & 12days
Period p1 = Period.ofYears(10); //P10Y - represents 10yrs
Period p2 = Period.ofMonths(14);//P14M - represents 14 months 
Period p3 = Period.ofDays(40);//P40D - represents 40 days 
Period p4 = Period.ofWeeks(2); //P14D - represents 14 days

static Period between(LocalDate startDateInclusive,
                      LocalDate endDateExclusive)

//Example usage of between() method
LocalDate d1 = LocalDate.of(2017, 3, 2); 
LocalDate d2 = LocalDate.of(2018, 3, 2); 
Period period12 = Period.between(d1, d2); // P1Y
Period period21 = Period.between(d2, d1); // P-1Y

//throws DateTimeParseException if text cannot be parsed as a Period
static Period parse(CharSequence text)

//Example usage of parse() method
Period period2 = Period.parse("P1Y17M20D"); // 1 year, 17 months, 20 days
Period period3 = Period.parse("P40D");// 40 days
Period period4 = Period.parse("P5W");// 35 days (5 weeks)
Period period5 = Period.parse("P-5W");// -35 days
Period period4 = Period.parse("-P2Y5D");// same as 'P-2Y-5D',-2 years & -5 days
Period pX = Period.parse("P24H"); // java.time.format.DateTimeParseException

The parse() method accepts strings of the format PnYnMnD or PnW where n represents a number and letters P,Y,M,D,W represents period, year, month, day and week respectively.The letters can exist in lower or upper-case. Each string must start with ‘P’ or ‘p’ and must include at-least one of the four sections – year, month, day or week.

As you know, period values can be negative. The parse() method allows to parse such a value. If you precede the complete argument value with ‘- ‘sign, it will be applied to all the values.

Another noteworthy point is that chaining of methods ofYears(),ofMonths(),ofDays() etc doesn’t produces the required result. Try it out.

Period period = Period.ofYears(5).ofMonths(10).ofDays(35);   // P35D. Logical error.
System.out.println(period);

Querying Period objects :

Following are some methods exposed by the API for querying purposes. They do exactly what their name suggest so we’ll avoid to discuss about them in much detail.

//Determines if any of the date based values is negative
boolean isNegative()

//Determines whether all date-based values are zero
boolean isZero()

//Compares a Period object with any other object
boolean equals(Object obj)

//Returns total number of months including year and month values,day value is simply ignored
long toTotalMonths()

//Returns specific date-based value
int getYears()
int getMonths()
int getDays()

Period class overrides equals() method from Object class. It is important to remember that this method compares each date-based value individually and they must match for this method to return true.For instance, periods ‘P1Y5M’ is not equal to ‘P17M’ and likewise.

Period p1 = Period.of(1, 14, 0);
Period p2 = Period.ofMonths(26);
System.out.println(p1.equals(p2));           // false

Modifying the Period object :

Period class provides withXXX() methods to return a modified copy of this object (as a new object, of-course, Remember : Period is immutable).

//sets specific date unit to the specified value
Period withYears(int years)
Period withMonths(int months)
Period withDays(int days)

Temporal Arithmetic with Periods :

Below are some temporal arithmetic methods you need to know for OCA Java 8 Exam.

//only alters that specific date based value, leaving rest of it as-is
Period minusYears/plusYears(long years)
Period minusMonths/plusMonths(long months)
Period minusDays/plusDays(long days)

//TemporalAmount is an interface implemented by Period
//This method throw DateTimeException is operation fails
//It doesn't performs any normalization
Period minus/plus(TemporalAmount amount)

//Returns a copy of the Period with month and years normalized, no impact on days
Period normalized()

//returns a new period with all date-based values negated
Period negated()

//returns a new Period with each date based value multiplied by scalar 
Period multipliedBy(int scalar)

Manipulating LocalDate and LocalDateTime using Period :

LocalDate & LocalDateTime also provides methods plus() and minus() which takes a Period argument and performs the manipulation based on the specified argument.

LocalDate date = LocalDate.of(2018, 01, 31);
System.out.println(date.plus(Period.ofDays(1)));// 2018-02-01

LocalDateTime dateTime = LocalDateTime.parse("2018-01-31T12:15:30");
System.out.println(dateTime.plus(Period.ofMonths(1)));//2018-02-28T12:15:30

LocalDate date = LocalDate.of(2018, 01, 31);
System.out.println(date.minus(Period.ofWeeks(4)));//2018-01-03

LocalTime cannot be used along with Period as it doesn’t contains any date-based value.

I know this article is a little too packed, covering a lot of details. But with a little practice, you are all set to answer any question on this topic. Keep on reviewing the concepts till you get it all. I am planning to cover DateTimeFormatter in the next blog post. Stay tuned!

Be the First to comment.

Leave a Comment

Your email address will not be published. Required fields are marked *