Querying LocalTime

You can use instance methods like getXX() to query LocalTime on its hour, minutes, seconds, and nanoseconds. All these methods return an int value:

LocalTime time = LocalTime.of(16, 20, 12, 98547);
System.out.println(time.getHour());
System.out.println(time.getMinute());
System.out.println(time.getSecond());
System.out.println(time.getNano());

Here’s the output:

16
20
12
98547
Exam Tip

The correct method names for querying LocalTime are get-Hour(), getMinute(), getSecond(), and getNano(). Watch out for exam questions that use invalid method names like getHours(), getMinutes(), getSeconds(), or getNanoSeconds().

You can use the instance methods isAfter() and isBefore() to check whether a time is after or before the specified time. The following code outputs true:

Manipulating LocalTime

You can use the instance methods minusHours(), minusMinutes(), minusSeconds(), and minusNanos() to create and return a copy of LocalTime instances with the specified period subtracted. The method names are self-explanatory. For example, minus-Hours(int) returns a copy of a LocalTime instance with the specified period in hours subtracted. The following example calculates and outputs the time when Shreya should leave from her office to watch a movie, given that the movie starts at 21:00 hours and it takes 35 minutes to commute to the movie theater:

LocalTime movieStartTime = LocalTime.parse("21:00:00");
int commuteMin = 35;
LocalTime shreyaStartTime = movieStartTime.minusMinutes(commuteMin);
System.out.println("Start by " + shreyaStartTime + " from office");

Here’s the output of the preceding code:

Start by 20:25 from office
Exam Tip

Unlike the getXXX() methods, minusXXX() methods use the plural form: getHour() versus minusHours(), getMinute() versus minusMinutes(), getSecond() versus minusSeconds(), and getNano() versus minusNanos().

The plusHours(), plusMinutes(), plusSeconds(), and plusNanos() methods accept long values and add the specified hours, minutes, seconds, or nanoseconds to time, returning its copy as LocalTime. The following example uses the addSeconds() and isAfter() methods to add seconds to a time and compares it with another time:

int worldRecord = 10;
LocalTime raceStartTime = LocalTime.of(8, 10, 55);
LocalTime raceEndTime = LocalTime.of(8, 11, 11);
if (raceStartTime.plusSeconds(worldRecord).isAfter(raceEndTime))
    System.out.println("New world record");
else
    System.out.println("Try harder");

The output of the preceding code looks like this:

Try harder
Exam Tip

LocalTime is immutable. Calling any method on its instance won’t modify its value.

The withHour(), withMinute(), withSecond(), and withNano() methods accept an int value and return a copy of LocalTime with the specified value altered. In the following example, a new LocalTime instance with the minute value 00 is created:

LocalTime startTime = LocalTime.of(5, 7, 9);
if (startTime.getMinute() < 30)
    startTime = startTime.withMinute(0);
System.out.println(startTime);

Here’s the output:

05:00:09
Combining with another type

The LocalTime class defines the atDate() method to combine a LocalDate with itself to create LocalDateTime:

LocalTime time = LocalTime.of(14, 10, 0);
LocalDate date = LocalDate.of(2016,02,28);
LocalDateTime dateTime = time.atDate(date);
System.out.println(dateTime);

Here’s the output:

2016-02-28T14:10
Exam Tip

The class LocalTime defines the method atDate(), which can be passed a LocalDate instance to create a LocalDateTime instance.

4.6.3. LocalDateTime

If you want to store both date and time (without the time zone), use the class LocalDateTime. It stores a value like 2050-06-18T14:20:30:908765 (year-month-dayThours:minutes:seconds:nanoseconds).

Note

The LocalDateTime class uses the letter T to separate date and time values in its printed value.

You can consider this class to offer the functionality of both the LocalDate and Local-Time classes. This class defines similar methods as those defined by the LocalDate and LocalTime classes. So instead of discussing individual methods of this class, here’s an example that covers the important methods of this class:

In the next section, you’ll discover how you can perform calculations with date and time using the Period class.

4.6.4. Period

People often talk about periods of years, months, or days. With the Java 8 Date API, you can use the Period class to do so. The Period class represents a date-based amount in years, months, and days, like 2 years, 5 months, and 10 days. To work with a time-based amount in seconds and nanoseconds, you can use the Duration class.

Note

The Duration class can be used to store amounts of time like 1 hour, 36 minutes, or 29.4 seconds. But this class isn’t explicitly covered in this exam (and this book). It’s covered in the OCP Java SE 8 Programmer II exam.

You can add or subtract Period instances from the LocalDate and LocalDateTime classes. Period is also an immutable class and hence safe to use in a multithreaded environment. Let’s get started by instantiating Period.

Instantiating Period

With a private constructor, the Period class defines multiple factory methods to create its instances. The static methods of(), ofYears(), ofMonths(), ofWeeks(), and ofDays() accept int values to create periods of years, months, weeks, or days:

Exam Tip

A period of 35 days is not stored as 1 month and 5 days. Its individual elements, that is, days, months, and years, are stored the way it is initialized.

You can also define negative periods by passing negative integer values to all the preceding methods. Here’s a quick example:

Exam Tip

You can define positive or negative periods of time. For example, you can define Period instances representing 15 or -15 days.

You can also parse a string to instantiate Period by using its static method parse. This method parses string values of the format PnYnMnD or PnW, where n represents a number and the letters (P, Y, M, D, and W) represent parse, year, month, day, and week. These letters can exist in lower- or uppercase. Each string must start with the letter p or P and must include at least one of the four sections, that is, year, month, week, or day. For the string format PnW, the count of weeks is multiplied by 7 to get the number of days. You can also define negative periods using parse(). If you precede the complete string value passed to parse() with a negative sign (-), it’s applied to all values. If you place a negative sign just before an individual number, it applies only to that section. Here are some examples to instantiate a period of five years (notice the use of uppercase and lowercase letters and + and – signs):

The following examples define periods of separate durations:

Period p5Yrs7 = Period.parse("P5y1m2d");
Period p5Yrs8 = Period.parse("p9m");
Period p5Yrs9 = Period.parse("P60d");
Period p5Yrs10 = Period.parse("-P5W");

When passed to System.out.println(), the variables in the preceding code will result in the following output:

P5Y1M2D
P9M
P60D
P-35D
Exam Tip

If you pass invalid string values to parse(), the code will compile but will throw a runtime exception.

You can also use the static method between(LocalDate dateInclusive, LocalDate dateExclusive) to instantiate Period:

Exam Tip

The static method between accepts two LocalDate instances and returns a Period instance representing the number of years, days, and months between the two dates. The first date is included, but the second date is excluded in the returned Period. Here’s a quick way to remember it: period = end date – start date.

Manipulating LocalDate and LocalDateTime using Period

In everyday life, it’s common to add or subtract periods of days, months, or years from a date. The Period class implements the interface TemporalAmount, so it can be used with the methods plus() and minus() defined in the classes LocalDateTime and LocalDate. The following example adds a period of a day to a LocalDate instance:

LocalDate date = LocalDate.of(2052, 01, 31);
System.out.println(date.plus(Period.ofDays(1)));

Here’s the output of the preceding code:

2052-02-01

What happens when you add a period of a month to January 31 of any year? Do you get the last day of February or the first day of March? The following example adds a period of a month to a LocalDateTime instance:

LocalDateTime dateTime = LocalDateTime.parse("2052-01-31T14:18:36");
System.out.println(dateTime.plus(Period.ofMonths(1)));

The output of the preceding code looks like this:

2052-02-29T14:18:36
Exam Tip

Because Period instances can represent positive or negative periods (like 15 days or -15 days), you can subtract days from a LocalDate or LocalDateTime by calling the method plus.

Similarly, you can use the method minus() with the classes LocalDate and LocalDateTime to subtract a period of years, months, weeks, or days:

LocalDateTime dateTime = LocalDateTime.parse("2020-01-31T14:18:36");
System.out.println(dateTime.minus(Period.ofYears(2)));

LocalDate date = LocalDate.of(2052, 01, 31);
System.out.println(date.minus(Period.ofWeeks(4)));

Here’s the output:

2018-01-31T14:18:36
2052-01-03
Querying Period instances

You can use the instance methods getYears(), getMonths(), and getDays() to query a Period instance on its years, months, and days. All these methods return an int value:

Period period = Period.of(2,4,40);
System.out.println(period.getYears());
System.out.println(period.getMonths());
System.out.println(period.getDays());

The preceding code outputs the following:

2
4
40
Exam Tip

When you initialize a Period instance with days more than 31 or months more than 12, it doesn’t recalculate its years, months, or days components-.

You can query whether any of three units of a Period is negative using the methods isNegative and isZero. A Period instance is zero if all three units are zero. The isNegative method returns true if at least one of its three components is strictly negative (<0):

Manipulating Period

You can use the instance methods minus(TemporalAmount), minusDays(long), minus-Weeks(long), minusMonths(long), minusYears(long), and multipliedBy(int) to create and return a copy of Period instances with the specified period subtracted or modified. The method names are self-explanatory. For an example, minusDays(long) returns a copy of a Period instance with the specified days subtracted. You can use the following example to send out reminders to your friends (limited to printing a message) for an event, say a birthday celebration, if it’s due in 10 days:

LocalDate bday = LocalDate.of(2020, 10, 29);
LocalDate today = LocalDate.now();
Period period10Days = Period.of(0, 0, 10);

if (bday.minus(period10Days).isBefore(today))
    System.out.println("Time to send out reminders to friends");
Exam Tip

In the class Period, both the getXXX() methods and minusXXX() methods use the plural form: getYears(), minusHours().

What happens when you subtract a Period representing one month (P1M) from a Period representing 10 days (P10D)? Would you get a Period representing 20 days or a Period representing -1 month and 10 days? Let’s find out using the following code, which also includes quick sample code on the usage of all the minusXXX methods:

Period period10Days = Period.of(0, 0, 10);
Period period1Month = Period.of(0, 1, 0);

System.out.println(period10Days.minus(period1Month));
System.out.println(period10Days.minusDays(5));
System.out.println(period10Days.minusMonths(5));
System.out.println(period10Days.minusYears(5));

Here’s the output:

P-1M10D
P5D
P-5M10D
P-5Y10D
Exam Tip

When you subtract Period instances using the minusXXX() methods, the individual elements are subtracted. Subtracting P10D from P1M returns P1M-10D and not P20D.

The Period class defines multipliedBy(int), which multiplies each element in the period by the integer value:

Exam Tip

The method multipliedBy(int) in the class Period is used to modify all elements of a Period instance. Period doesn’t define a “divideBy()” method. Both the getXXX() methods and minusXXX() methods use the plural form getYears(), minusHours().

The plus(TemporalAmount), plusDays(long), plusWeeks(long), plusMonths(long), and plusYears(long) methods add to Period instances and return the modified value as a Period. Like the minusXXX() methods, all the plusXXX() methods add individual elements:

Period period5Month = Period.of(0, 5, 0);
Period period10Month = Period.of(0, 10, 0);
Period period10Days = Period.of(0, 0, 10);

System.out.println(period5Month.plus(period10Month));
System.out.println(period10Days.plusDays(35));
System.out.println(period10Days.plusMonths(5));
System.out.println(period10Days.plusYears(5));

The output of the preceding code is as follows:

P15M
P45D
P5M10D
P5Y10D
Exam Tip

Adding a Period of 10 months to a Period of 5 months gives 15 months, not 1 year and 3 months.

The withDays(), withMonths(), and withYears() methods accept an int value and return a copy of Period with the specified value altered.

Converting to another type

The method toTotalMonths() returns the total number of months in the period by multiplying the number of years by 12 and adding the number of months:

A Period can be used as an argument to the LocalDate one-parameter plus() and minus() methods. What happens when you want to add 3 months and 10 days to a given date? The number of months per year is constant but the number of days per month isn’t. A glimpse at the plus() and minus() methods in the LocalDate source code shows that years are converted to months and months are always handled before days.

In the next section, you’ll work with the class DateTimeFormatter.

4.6.5. DateTimeFormatter

Defined in the package java.time.format, the class DateTimeFormatter can be used to format and parse date and time objects. In this section, you’ll use this class to format or parse date and time objects using predefined constants (like ISO_LOCAL_DATE), using patterns (like yyyy-MM-dd) or localized styles like long or short.

The first step to format or parse a date or time object is to access a DateTime-Formatter and then call format or parse methods on either date or time objects or DateTimeFormatter. Let’s work in detail with these steps, starting with multiple ways to instantiate or access a DateTimeFormatter object.

Instantiate or access DateTimeFormatter

You can instantiate or access a DateTimeFormatter object in multiple ways:

  • By calling a static ofXXX method, passing it a FormatStyle value
  • By access public static fields of DateTimeFormatter
  • By using the static method ofPattern and passing it a string value

Starting with the first option, you can instantiate a DateTimeFormatter to work with date, time, or date/time objects by calling its ofXXX static method and passing it a FormatStyle value (FormatStyle.FULL, FormatStyle.LONG, FormatStyle.MEDIUM, or FormatStyle.SHORT):

DateTimeFormatter formatter1 =
                  DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);
DateTimeFormatter formatter2 =
                  DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL);
DateTimeFormatter formatter3 =
                  DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
DateTimeFormatter formatter4 =
                  DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT,
                                                        FormatStyle.SHORT);
Note

The methods ofLocalizedDate, ofLocalizedTime, and ofLocalizedDateTime format date and time objects according to the locale (language, region, or country) of the system on which your code executes. So the output might vary slightly across systems.

Table 4.2 shows how a date or time object will be formatted by using the different Format-Style values.

Table 4.2. Examples of how FormatStyle affects formatting of a date (say, August 11, 2057) or time (say, 14 hours, 30 minutes, and 15 seconds) object

FormatStyle

Example

FormatStyle.FULL Saturday, August 11, 2057
FormatStyle.LONG August 11, 2057
FormatStyle.MEDIUM Aug 11, 2057
FormatStyle.SHORT 8/11/57
FormatStyle.FULL  
FormatStyle.LONG  
FormatStyle.MEDIUM 2:30:15 PM
FormatStyle.SHORT 2:30 PM

You can access a DateTimeFormatter object by using the public and static fields of this class:

DateTimeFormatter formatter5 = DateTimeFormatter.ISO_DATE;

Table 4.3 lists a few predefined formatters that are relevant for this exam.

Table 4.3. Predefined formatters in the class DateTimeFormatter and an example of how they format a date (say, August 11, 2057) or time (say, 14 hours 30 minutes, and 15 seconds) object

Predefined formatter

Example

BASIC_ISO_DATE 20570811
ISO_DATE/ISO_LOCAL_DATE 2057-08-11
ISO_TIME/ISO_LOCAL_TIME 14:30:15.312
ISO_DATE_TIME/ISO_LOCAL_DATE_TIME 2057-08-11T14:30:15.312

You can instantiate a DateTimeFormatter using a pattern (of letters and symbols) by using the static method ofPattern and passing it a string value:

DateTimeFormatter formatter6= DateTimeFormatter.ofPattern("yyyy MM dd");

You can use the preceding code to format a date, say August 11, 2057, as 2057 08 11. Table 4.4 lists the letters that can be used to define such patterns.

Table 4.4. Letters used to define patterns for DateTimeFormatter and examples of how they would format a date (say, August 11, 2057) or time (say, 14 hours, 30 minutes, and 15 seconds) object

Symbol

Meaning

Example

y, Y year 2057; 57
M month of year 8; 08; Aug; August
D day of year 223
d day of month 11
E day of week Sat
e localized day of week 7; Sat
a a.m. or p.m. of day pm
h clock hour of a.m./p.m. 03
H hour of day 14
m minute of hour 30
s second of minute 15
' escape for text  
Exam Tip

A DateTimeFormatter can define rules to format or parse a date object, time object, or both.

Format date or time objects using DateTimeFormatter

To format a date or time object, you can use either the instance format method in date/time objects or the instance format method in the DateTimeFormatter class. Behind the scenes, the format method in date and time objects simply calls the format method in DateTimeFormatter. Table 4.5 lists the available format methods.

Note

TemporalAccessor is an interface, implemented by the classes LocalDate, LocalTime, and LocalDateTime. You won’t get explicit questions on this interface on the exam.

Table 4.5. format methods in the classes LocalDate, LocalTime, LocalDateTime, and Date-TimeFormatter

Defined in

Return type

Method signature and description

LocalDate String format(DateTimeFormatter) Formats this date object using the specified DateTimeFormatter
LocalTime String format(DateTimeFormatter) Formats this time object using the specified DateTimeFormatter
LocalDateTime String format(DateTimeFormatter) Formats this date/time object using the specified DateTimeFormatter
DateTimeFormatter String format(TemporalAccessor) Formats a date/time object using this formatter
Exam Tip

Watch out for the count and type of arguments passed to the instance method format. When calling format on a LocalDate, LocalTime, or LocalDateTime instance, pass a DateTimeFormatter instance as a method parameter. When calling format on DateTimeFormatter, pass a LocalDate, LocalTime, or LocalDateTime instance as a method argument.

The method format in DateTimeFormatter formats a date or time object to a String using the rules of the formatter. The following example formats a LocalDate object using the style FormatStyle (styles are listed in table 4.2):

What happens if you pass a time object (LocalTime) instead of a date object (LocalDate) in the preceding code? Will it compile or execute successfully (changes are shown in bold)?

The preceding code will compile successfully but won’t execute. It will throw a runtime exception because the formatter defines rules to format a date object (created using ofLocalizedDate()), but its format() is passed a time object.

Exam Tip

If you pass a date object to the method format on a DateTimeFormatter instance that defines rules to format a time object, it will throw a runtime exception.

Formatting date and time objects using DateTimeFormatter, which are created using string patterns, is interesting (and confusing). Take note of the case of the letters used in the patterns. M and m or D and d are not the same. Also, using a pattern letter doesn’t specify the count of digits or texts. For an example, using Y or YYYY to format a date object returns the same results. Following are examples that use different patterns:

LocalDate date = LocalDate.of(2057,8,11);
LocalTime time = LocalTime.of(14,30,15);

DateTimeFormatter d1 = DateTimeFormatter.ofPattern("y");
DateTimeFormatter d2 = DateTimeFormatter.ofPattern("YYYY");
DateTimeFormatter d3 = DateTimeFormatter.ofPattern("Y M D");
DateTimeFormatter d4 = DateTimeFormatter.ofPattern("e");

DateTimeFormatter t1 = DateTimeFormatter.ofPattern("H h m s");
DateTimeFormatter t2 = DateTimeFormatter.ofPattern("'Time now:'HH mm a");

System.out.println(d1.format(date));
System.out.println(d2.format(date));
System.out.println(d3.format(date));
System.out.println(d4.format(date));

System.out.println(t1.format(time));
System.out.println(t2.format(time));

Here’s the output of the preceding code:

2057
2057
2057 8 223
7
14 2 30 15
Time now:14 30 PM
Exam Tip

If you're confused between M, m, D, and d, remember that an uppercase letter represents a bigger duration period. So M is for month and m is for minutes. Similarly, D represents day of year; d represents day of month.

You can also format date and time objects by calling the format method in date or time objects and passing it a DateTimeFormatter instance.

Note

If you access Java’s source code, you’ll notice that the format and parse methods in date and time classes simply call the format and parse methods on a DateTimeFormatter instance.

Parse date or time objects using DateTimeFormatter

To parse a date or time object, you can use either the static parse method in date/time objects or the instance parse method in the DateTimeFormatter class. Behind the scenes, the parse method in date/time objects simply calls the parse method in DateTimeFormatter. Table 4.6 lists the available parse methods.

Exam Tip

The parse methods are defined as static methods in the classes LocalDate, LocalTime, and LocalDateTime. The class DateTimeFormatter defines the parse method as an instance method.

Table 4.6. parse methods in the classes LocalDate, LocalTime, LocalDateTime, and Date-TimeFormatter

Defined in

Return type

Method signature and description

LocalDate LocalDate parse(CharSequence) Creates a LocalDate instance using a text string such as 2057-08-11, parsed using DateTimeFormatter.ISO_LOCAL_DATE
LocalDate LocalDate parse(CharSequence, DateTimeFormatter) Creates a LocalDate instance, parsing text using the specified formatter
LocalTime LocalTime parse(CharSequence) Creates a LocalTime instance using a text string such as 14:40, parsed using Date-TimeFormatter.ISO_LOCAL_TIME
LocalTime LocalTime parse(CharSequence, DateTimeFormatter) Creates a LocalTime instance, parsing text using the specified formatter
LocalDateTime LocalDateTime parse(CharSequence) Creates a LocalDateTime instance using a text string such as 2057-08-11T14:40, parsed using DateTimeFormatter.ISO_LOCAL_DATE_TIME
LocalDateTime LocalDateTime parse(CharSequence, DateTimeFormatter) Creates a LocalDateTime instance, parsing text using the specified formatter
DateTimeFormatter TemporalAccessor parse(CharSequence) Parses text using the rules of DateTime-Formatter, returning a temporal object
Exam Tip

When calling parse on LocalDate, LocalTime, or LocalDateTime instances, you might not specify a formatter. In this case DateTimeFormatter.ISO_LOCAL_DATE, DateTimeFormatter.ISO_LOCAL_TIME, and DateTimeFormatter.ISO_LOCAL_DATE_TIME are used to parse text, respectively.

Let’s work with the method parse of LocalDate, LocalTime, or LocalDateTime to parse a string value using a DateTimeFormatter, producing a date or time object:

DateTimeFormatter d1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate date = LocalDate.parse("2057-01-29", d1 );

The following line throws a DateTimeParseException because this mechanism works only if all components are present. For example, the pattern yyyy-MM-dd with “2057-01-29” works fine. The component order doesn’t matter; hence, using dd-yyyy-MM to parse “29-2057-01” works too and yields January 29, 2057 as well:

DateTimeFormatter d1 = DateTimeFormatter.ofPattern("yyyy");
LocalDate date = LocalDate.parse("2057", d1);

Similarly, you can call the parse method to create instances of LocalTime and LocalDateTime.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.101.81