Working with Optional and Date-Time API Fundamentals
Course: Core Java Training
Topic: Working with Optional and Date-Time API Fundamentals
Course Link: Core Java Training – JustAcademy
Demo Link: Register for a Course Demo
Website: JustAcademy Official Website
1. Introduction
Java 8 introduced several important features that make everyday programming safer and easier. Two useful additions are the Optional class and the modern Date-Time API.
Optional represents a value that may or may not be available. It helps developers communicate the possibility of a missing result and handle that situation explicitly instead of relying on unexpected null values.
The Date-Time API, provided mainly through the java.time package, offers clear classes for working with dates, times, time zones, durations, and date calculations. These classes improve upon many limitations of older date and calendar APIs.
2. Learning Objectives
- Understand the purpose of Optional in Java.
- Create Optional objects using different factory methods.
- Handle missing values using methods such as
orElse(), orElseGet(), and orElseThrow().
- Use Optional with
map(), filter(), and flatMap().
- Understand the main classes in the Java Date-Time API.
- Create, format, parse, compare, and manipulate dates and times.
- Work with time zones, periods, and durations.
- Apply Optional and Date-Time API features in practical Java programs.
3. Understanding Optional in Java
Optional<T> is a container object that may contain a non-null value of type T or may be empty. It is part of the java.util package.
Optional is especially useful when a method might not find a result. For example, a method searching for a user by ID may return a user when one exists or an empty result when no user is found.
Why Is Optional Needed?
Before Optional, developers often returned null to indicate that a value was unavailable. If the calling code attempted to access a method on that null reference, the program could throw a NullPointerException.
Example Without Optional
public class NullExample {
public static String findUserName() {
return null;
}
public static void main(String[] args) {
String name = findUserName();
if (name != null) {
System.out.println(name.toUpperCase());
} else {
System.out.println("User name not found");
}
}
}
Output:
User name not found
The null check prevents the program from calling toUpperCase() on a missing value. Optional provides another way to model and handle this situation.
4. Creating Optional Objects
Java provides several static factory methods for creating Optional objects.
| Method |
Description |
Example |
Optional.of(value) |
Creates an Optional containing a non-null value. Throws NullPointerException if the value is null. |
Optional.of("Java") |
Optional.ofNullable(value) |
Creates a populated Optional for a non-null value or an empty Optional for null. |
Optional.ofNullable(name) |
Optional.empty() |
Creates an empty Optional. |
Optional.empty() |
Example: Using Optional.of()
import java.util.Optional;
public class OptionalOfDemo {
public static void main(String[] args) {
Optional<String> language =
Optional.of("Java");
System.out.println(language.get());
}
}
Output:
Java
Use Optional.of() only when the value is known to be non-null.
Example: Using Optional.ofNullable()
import java.util.Optional;
public class OptionalNullableDemo {
public static void main(String[] args) {
String name = null;
Optional<String> result =
Optional.ofNullable(name);
System.out.println(result.isPresent());
}
}
Output:
false
This method safely handles a potentially null value by producing an empty Optional.
Example: Using Optional.empty()
import java.util.Optional;
public class OptionalEmptyDemo {
public static void main(String[] args) {
Optional<String> result = Optional.empty();
System.out.println(result.isPresent());
System.out.println(result.orElse("No value available"));
}
}
Output:
false
No value available
5. Checking Whether a Value Is Present
Optional provides methods for checking whether it contains a value and for performing an action when the value is available.
isPresent()
Returns true if a value is present and false if the Optional is empty.
ifPresent()
Executes the supplied action only when a value is present.
import java.util.Optional;
public class OptionalCheckDemo {
public static void main(String[] args) {
Optional<String> name =
Optional.of("Priya");
if (name.isPresent()) {
System.out.println(name.get());
}
name.ifPresent(value ->
System.out.println("Welcome " + value)
);
}
}
Output:
Priya
Welcome Priya
In Java 9 and later, ifPresentOrElse() can execute one action when a value exists and another when the Optional is empty. This method is not available in Java 8.
6. Retrieving Values from Optional
Optional offers several methods for obtaining a value or providing a fallback when no value exists.
| Method |
Behavior |
get() |
Returns the value if present; throws NoSuchElementException if empty. |
orElse(defaultValue) |
Returns the value or the supplied fallback value. |
orElseGet(supplier) |
Returns the value or obtains a fallback from a Supplier. |
orElseThrow() |
Returns the value or throws NoSuchElementException when empty. The no-argument form was added in Java 10. |
orElseThrow(supplier) |
Returns the value or throws an exception created by the supplied function. |
Example: Using orElse()
import java.util.Optional;
public class OrElseDemo {
public static void main(String[] args) {
Optional<String> username =
Optional.empty();
String result = username.orElse("Guest");
System.out.println(result);
}
}
Output:
Guest
Example: Using orElseGet()
import java.util.Optional;
public class OrElseGetDemo {
public static void main(String[] args) {
Optional<String> username =
Optional.empty();
String result = username.orElseGet(
() -> "Guest User"
);
System.out.println(result);
}
}
Output:
Guest User
The Supplier passed to orElseGet() is evaluated only when the Optional is empty.
Difference Between orElse() and orElseGet()
String a = optional.orElse(createDefault());
String b = optional.orElseGet(() -> createDefault());
In the first statement, createDefault() is evaluated before orElse() is called, even if the Optional contains a value. In the second statement, the Supplier is invoked only if the Optional is empty. This distinction matters when fallback creation is expensive or has side effects.
7. Transforming Values with map()
The map() method transforms a value inside an Optional when it is present. If the Optional is empty, the transformation is skipped and the result remains empty.
Example: Converting a Name to Uppercase
import java.util.Optional;
public class OptionalMapDemo {
public static void main(String[] args) {
Optional<String> name =
Optional.of("amit");
Optional<String> result =
name.map(String::toUpperCase);
System.out.println(result.orElse("Unknown"));
}
}
Output:
AMIT
The method reference String::toUpperCase transforms the contained string. If the Optional were empty, the mapping operation would not execute.
8. Filtering Values with filter()
The filter() method keeps a value only if it satisfies a supplied condition. If the value fails the condition, the result is an empty Optional.
Example: Checking an Age
import java.util.Optional;
public class OptionalFilterDemo {
public static void main(String[] args) {
Optional<Integer> age =
Optional.of(22);
Optional<Integer> eligibleAge =
age.filter(value -> value >= 18);
System.out.println(
eligibleAge.orElse(0)
);
}
}
Output:
22
If the age were 16, the filtered Optional would be empty and the displayed fallback would be 0.
9. Using flatMap()
The flatMap() method is useful when the transformation function already returns an Optional. It avoids creating nested structures such as Optional<Optional<String>>.
Example: Finding a Department
import java.util.Optional;
class Employee {
private final String department;
Employee(String department) {
this.department = department;
}
Optional<String> getDepartment() {
return Optional.ofNullable(department);
}
}
public class OptionalFlatMapDemo {
public static void main(String[] args) {
Optional<Employee> employee =
Optional.of(new Employee("IT"));
Optional<String> department =
employee.flatMap(Employee::getDepartment);
System.out.println(
department.orElse("Not assigned")
);
}
}
Output:
IT
The getDepartment() method returns an Optional. Using flatMap() keeps the result as a single Optional rather than wrapping it inside another Optional.
10. Handling Exceptions with Optional
Optional can be used to express the absence of a result, but it does not automatically catch exceptions. When an operation may fail, handle the relevant exception explicitly or use orElseThrow() to report a missing value.
import java.util.Optional;
public class OptionalExceptionDemo {
public static void main(String[] args) {
Optional<String> email =
Optional.empty();
String value = email.orElseThrow(
() -> new IllegalStateException(
"Email address is required"
)
);
System.out.println(value);
}
}
This program throws an IllegalStateException because the Optional is empty. In a real application, choose an exception that accurately represents the failure.
11. Best Practices for Optional
- Use Optional primarily as a return type when a method may legitimately have no result.
- Use
Optional.ofNullable() when converting a value that may be null.
- Avoid calling
get() without first establishing that a value is present.
- Prefer
orElse(), orElseGet(), or orElseThrow() when their behavior fits the requirement.
- Use
map() and filter() to transform or validate an optional value.
- Use
flatMap() when the transformation itself returns an Optional.
- Do not treat Optional as a universal replacement for every nullable field, method parameter, or collection.
- Remember that Optional itself should not be null; use an empty Optional to represent the absence of a value.
12. Introduction to the Java Date-Time API
The Java Date-Time API was introduced in Java 8 under the java.time package. It provides separate classes for dates, times, date-time combinations, time zones, and amounts of time.
The modern API is designed around immutable value objects. Date and time values are not modified in place; operations such as adding days return a new value. This design makes the API easier to reason about and safer to use across multiple threads.
Limitations of Older Date-Time Classes
- The older
Date and Calendar APIs can be less intuitive to use.
- Older date and time handling often requires extra conversion and formatting code.
SimpleDateFormat is not thread-safe when shared across threads without proper protection.
- Separating a date, a local time, an instant, and a time-zone-aware value is less clear in some older APIs.
13. Important Classes in java.time
| Class |
Purpose |
Example |
LocalDate |
Represents a date without a time or time zone. |
2026-10-26 |
LocalTime |
Represents a time without a date or time zone. |
14:30:00 |
LocalDateTime |
Represents a date and time without a time zone. |
2026-10-26T14:30:00 |
ZonedDateTime |
Represents a date and time associated with a time zone. |
2026-10-26T14:30+05:30[Asia/Kolkata] |
Instant |
Represents a point on the global timeline. |
2026-10-26T09:00:00Z |
Period |
Represents a date-based amount in years, months, and days. |
2 years, 3 months, 4 days |
Duration |
Represents a time-based amount, typically in seconds and nanoseconds. |
3600 seconds |
YearMonth |
Represents a year and month without a specific day. |
2026-10 |
MonthDay |
Represents a month and day without a year. |
--10-26 |
DateTimeFormatter |
Formats and parses date-time values. |
26-10-2026 |
14. Working with LocalDate
LocalDate represents a calendar date without a time or time zone. It is useful for birthdays, joining dates, deadlines, appointment dates, and holidays.
Creating a Date
import java.time.LocalDate;
public class LocalDateDemo {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
LocalDate joiningDate =
LocalDate.of(2025, 6, 15);
System.out.println(today);
System.out.println(joiningDate);
}
}
The value returned by LocalDate.now() depends on the system's clock and default time zone, so its output can change.
Adding and Subtracting Dates
import java.time.LocalDate;
public class DateCalculationDemo {
public static void main(String[] args) {
LocalDate date =
LocalDate.of(2026, 1, 10);
System.out.println(date.plusDays(7));
System.out.println(date.plusMonths(2));
System.out.println(date.minusDays(3));
}
}
Output:
2026-01-17
2026-03-10
2026-01-07
These operations return new LocalDate objects. The original date remains unchanged.
15. Working with LocalTime
LocalTime represents a time without a date or time zone. It is useful for opening hours, daily schedules, and times entered by users.
import java.time.LocalTime;
public class LocalTimeDemo {
public static void main(String[] args) {
LocalTime now = LocalTime.now();
LocalTime openingTime =
LocalTime.of(9, 30);
System.out.println(now);
System.out.println(openingTime);
System.out.println(openingTime.plusHours(2));
}
}
Example output for the fixed values:
09:30
11:30
The current time output varies. The exact formatting may also omit seconds when they are zero.
16. Working with LocalDateTime
LocalDateTime combines a date and a time, but it does not identify a time zone or a unique global instant. It is suitable for local date-time values when zone information is not required.
import java.time.LocalDateTime;
public class LocalDateTimeDemo {
public static void main(String[] args) {
LocalDateTime appointment =
LocalDateTime.of(2026, 10, 26, 14, 30);
System.out.println(appointment);
System.out.println(appointment.plusDays(2));
}
}
Output:
2026-10-26T14:30
2026-10-28T14:30
Use a time-zone-aware class when the date-time must refer to a specific geographic region or global instant.
17. Working with ZonedDateTime and Time Zones
ZonedDateTime represents a date and time with a time zone. It is important for applications that schedule meetings across countries, process travel itineraries, or handle business events in different regions.
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class ZonedDateTimeDemo {
public static void main(String[] args) {
ZonedDateTime indiaTime =
ZonedDateTime.now(
ZoneId.of("Asia/Kolkata")
);
ZonedDateTime londonTime =
indiaTime.withZoneSameInstant(
ZoneId.of("Europe/London")
);
System.out.println("India: " + indiaTime);
System.out.println("London: " + londonTime);
}
}
The output depends on the current instant and the applicable time-zone rules. withZoneSameInstant() preserves the instant while displaying it in another zone.
LocalDateTime vs. ZonedDateTime
| LocalDateTime |
ZonedDateTime |
| Contains date and time only. |
Contains date, time, and time-zone information. |
| Does not identify one unique instant by itself. |
Includes zone rules to resolve the local date-time and offset. |
| Useful for a local appointment time when no zone is needed. |
Useful for events that must be coordinated across time zones. |
18. Working with Instant
Instant represents a specific point on the global timeline, commonly expressed in UTC. It is useful for event timestamps, logs, audit records, and measuring elapsed time between events.
import java.time.Instant;
public class InstantDemo {
public static void main(String[] args) {
Instant start = Instant.now();
// Perform an operation here.
Instant end = Instant.now();
System.out.println("Start: " + start);
System.out.println("End: " + end);
}
}
Instant values are normally displayed with a trailing Z to indicate UTC. The printed timestamps vary each time the program runs.
19. Formatting Dates with DateTimeFormatter
DateTimeFormatter allows date-time values to be converted into readable strings. It can also parse formatted text into appropriate date-time objects.
Example: Formatting a Date
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class DateFormattingDemo {
public static void main(String[] args) {
LocalDate date =
LocalDate.of(2026, 10, 26);
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("dd-MM-yyyy");
System.out.println(date.format(formatter));
}
}
Output:
26-10-2026
Common Formatting Symbols
| Symbol |
Meaning |
Example |
dd |
Day of month, two digits |
05 |
MM |
Month number, two digits |
10 |
MMM |
Short month name |
Oct |
MMMM |
Full month name |
October |
yyyy |
Year |
2026 |
HH |
Hour in 24-hour format |
14 |
hh |
Hour in 12-hour format |
02 |
mm |
Minute |
30 |
ss |
Second |
45 |
a |
AM/PM marker |
PM |
Use uppercase MM for the month and lowercase mm for minutes. These symbols are not interchangeable.
20. Parsing Date Strings
Parsing means converting text into a date-time object. The input string must match the expected format, otherwise parsing can fail with a DateTimeParseException.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class DateParsingDemo {
public static void main(String[] args) {
String input = "26-10-2026";
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("dd-MM-yyyy");
LocalDate date =
LocalDate.parse(input, formatter);
System.out.println(date);
}
}
Output:
2026-10-26
Parsing is useful when dates arrive from forms, configuration files, APIs, or user input.
21. Comparing Dates and Times
The Date-Time API provides comparison methods that help determine the order of dates and times.
isBefore() checks whether a value occurs before another value.
isAfter() checks whether a value occurs after another value.
isEqual() checks whether two temporal values represent the same date or instant according to the class's semantics.
equals() checks object value equality.
import java.time.LocalDate;
public class DateComparisonDemo {
public static void main(String[] args) {
LocalDate today =
LocalDate.of(2026, 10, 26);
LocalDate deadline =
LocalDate.of(2026, 11, 1);
System.out.println(today.isBefore(deadline));
System.out.println(today.isAfter(deadline));
}
}
Output:
true
false
22. Understanding Period
Period represents a date-based amount of time in years, months, and days. It is useful for calculating age-related intervals, subscription periods, and calendar-based deadlines.
import java.time.LocalDate;
import java.time.Period;
public class PeriodDemo {
public static void main(String[] args) {
LocalDate start =
LocalDate.of(2020, 1, 10);
LocalDate end =
LocalDate.of(2025, 4, 15);
Period period = Period.between(start, end);
System.out.println(period.getYears());
System.out.println(period.getMonths());
System.out.println(period.getDays());
}
}
Output:
5
3
5
The Period represents the calendar-based difference between the two dates: 5 years, 3 months, and 5 days.
23. Understanding Duration
Duration represents an amount of time on the timeline, such as seconds, minutes, or hours. It is commonly used to measure elapsed time between two time-based values.
import java.time.Duration;
import java.time.LocalTime;
public class DurationDemo {
public static void main(String[] args) {
LocalTime start =
LocalTime.of(10, 0);
LocalTime end =
LocalTime.of(12, 30);
Duration duration =
Duration.between(start, end);
System.out.println(duration.toHours());
System.out.println(duration.toMinutes());
}
}
Output:
2
150
Period vs. Duration
| Period |
Duration |
| Represents calendar-based years, months, and days. |
Represents elapsed time in seconds and nanoseconds. |
| Useful for date-based calculations. |
Useful for measuring elapsed time between time-based values. |
| Example: 2 months and 5 days. |
Example: 3,600 seconds. |
24. Working with YearMonth and MonthDay
YearMonth represents a particular year and month without a specific day. It is useful for monthly reports and credit-card expiry dates.
import java.time.YearMonth;
public class YearMonthDemo {
public static void main(String[] args) {
YearMonth expiry =
YearMonth.of(2028, 6);
System.out.println(expiry);
System.out.println(expiry.plusMonths(1));
}
}
Output:
2028-06
2028-07
MonthDay represents a month and day without a year, making it useful for recurring annual dates such as birthdays.
import java.time.MonthDay;
public class MonthDayDemo {
public static void main(String[] args) {
MonthDay birthday =
MonthDay.of(12, 25);
System.out.println(birthday);
}
}
Output:
--12-25
25. Combining Optional with the Date-Time API
Optional and the Date-Time API can be combined when a date may not be available. For example, a system may not have an employee's joining date recorded. An Optional can represent the missing date and provide a suitable fallback.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Optional;
public class OptionalDateDemo {
public static void main(String[] args) {
Optional<LocalDate> joiningDate =
Optional.ofNullable(null);
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("dd-MM-yyyy");
String result = joiningDate
.map(date -> date.format(formatter))
.orElse("Joining date not available");
System.out.println(result);
}
}
Output:
Joining date not available
The map() operation formats the date only when it is present. If the Optional is empty, orElse() provides the fallback message.
26. Practical Example: Employee Joining Date Manager
This program demonstrates Optional, LocalDate, Period, and DateTimeFormatter together to handle an employee's joining date and calculate the elapsed calendar period.
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.Optional;
public class EmployeeJoiningDateManager {
public static void main(String[] args) {
Optional<LocalDate> joiningDate =
Optional.of(LocalDate.of(2022, 5, 10));
LocalDate today = LocalDate.now();
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("dd-MM-yyyy");
joiningDate.ifPresent(date -> {
System.out.println(
"Joining Date: " + date.format(formatter)
);
Period servicePeriod =
Period.between(date, today);
System.out.println(
"Years of Service: " +
servicePeriod.getYears()
);
System.out.println(
"Months: " + servicePeriod.getMonths()
);
System.out.println(
"Days: " + servicePeriod.getDays()
);
});
String displayDate = joiningDate
.map(date -> date.format(formatter))
.orElse("Joining date not available");
System.out.println("Display: " + displayDate);
}
}
Explanation:
- The joining date is stored inside an Optional.
LocalDate.now() obtains the current date from the system clock.
DateTimeFormatter displays the date in day-month-year format.
Period.between() calculates the calendar-based difference between the joining date and today.
ifPresent() ensures that the date calculation is performed only when a date exists.
orElse() provides a fallback message if the joining date is missing.
The calculated service period changes according to the date on which the program runs.
27. Common Errors and Troubleshooting
Error 1: Calling get() on an Empty Optional
Problem: Calling get() when an Optional is empty throws NoSuchElementException.
Solution: Use orElse(), orElseGet(), or orElseThrow(), or check whether a value is present before retrieving it.
Error 2: Passing Null to Optional.of()
Problem: Optional.of(null) throws NullPointerException.
Solution: Use Optional.ofNullable(value) when the value may be null.
Error 3: Incorrect Date Format
Problem: Parsing fails because the input string does not match the formatter pattern.
Solution: Verify the order and meaning of the pattern symbols. For example, use dd-MM-yyyy for a string such as 26-10-2026.
Error 4: Assuming Date-Time Objects Change in Place
Problem: Calling date.plusDays(5) without storing the returned value does not change the original LocalDate.
Solution: Assign the result to a variable, for example date = date.plusDays(5).
Error 5: Confusing LocalDateTime with a Zoned Time
Problem: A LocalDateTime does not contain a time zone and cannot by itself identify a unique instant globally.
Solution: Use ZonedDateTime or OffsetDateTime when time-zone or UTC-offset information is required.
28. Best Practices for the Date-Time API
- Prefer the modern
java.time classes for new Java applications.
- Use
LocalDate for dates, LocalTime for times, and LocalDateTime for local date-time values.
- Use
ZonedDateTime or OffsetDateTime when the time zone or UTC offset matters.
- Use
Instant for globally comparable timestamps and event logging.
- Use
Period for calendar-based differences and Duration for elapsed time.
- Use
DateTimeFormatter for consistent parsing and display.
- Remember that date-time objects are immutable and store the result of calculations when needed.
- Choose time zones explicitly in applications that handle users in different regions.
- Use Optional to represent a missing result, not as a replacement for clear validation or error handling.
29. Practice Exercises
Exercise 1: Optional User Name
Create an Optional that contains a user name. Display the name in uppercase if present; otherwise, display "Guest".
Exercise 2: Optional Email Address
Create an Optional for an email address that may be null. Use orElse() to provide a fallback message.
Exercise 3: Date Calculations
Create a LocalDate for a project start date. Calculate the date 30 days later and the date one month earlier.
Exercise 4: Date Formatting
Parse a date string in dd-MM-yyyy format and display it in MMMM dd, yyyy format.
Exercise 5: Calculate Age
Use LocalDate and Period to calculate the calendar-based age between a date of birth and the current date.
Exercise 6: Compare Deadlines
Create two LocalDate values and determine which date occurs first using isBefore() and isAfter().
Exercise 7: Optional Joining Date
Create an Optional containing a LocalDate. Display the formatted joining date if present and a fallback message if absent.
30. Interview Questions and Answers
Q1. What is Optional in Java?
Optional is a container object that may contain a non-null value or be empty. It helps represent potentially missing results explicitly.
Q2. What is the difference between Optional.of() and Optional.ofNullable()?
Optional.of() requires a non-null value and throws NullPointerException for null. Optional.ofNullable() creates an empty Optional when the supplied value is null.
Q3. What is the difference between orElse() and orElseGet()?
orElse() receives a fallback value that is evaluated before the call. orElseGet() receives a Supplier that is evaluated only when the Optional is empty.
Q4. What are map() and flatMap() used for in Optional?
map() transforms a contained value. flatMap() is used when the transformation itself returns an Optional, avoiding nested Optional objects.
Q5. What is the Java Date-Time API?
It is the modern date and time API introduced in Java 8, primarily in the java.time package. It provides specialized classes for dates, times, time zones, and time amounts.
Q6. What is the difference between LocalDate and LocalDateTime?
LocalDate stores a date only, while LocalDateTime stores both a date and a time. Neither includes a time zone.
Q7. What is the difference between Period and Duration?
Period represents calendar-based amounts in years, months, and days. Duration represents elapsed time in seconds and nanoseconds.
Q8. Why are java.time classes considered safer to use?
The core date-time value classes are immutable and thread-safe, reducing risks associated with shared mutable date-time objects.
Q9. What is DateTimeFormatter used for?
It formats date-time objects into strings and parses formatted strings into date-time objects.
Q10. When should ZonedDateTime be used?
Use ZonedDateTime when the date and time must be associated with a specific time zone and its applicable time-zone rules.
Q11. Can Optional prevent every NullPointerException?
No. Optional helps model missing values when used appropriately, but null references elsewhere in a program can still cause NullPointerException.
Q12. Are LocalDate and LocalDateTime mutable?
No. They are immutable. Methods such as plusDays() return new instances instead of changing the original object.
31. Quick Revision Checklist
- Optional represents a present or absent value.
of(), ofNullable(), and empty() create Optional instances.
orElse() and orElseGet() provide fallback values in different ways.
map() transforms an optional value; filter() applies a condition.
flatMap() helps avoid nested Optional objects.
LocalDate stores a date; LocalTime stores a time.
LocalDateTime stores a date and time without a zone.
ZonedDateTime includes time-zone information.
Instant represents a point on the global timeline.
DateTimeFormatter formats and parses date-time values.
Period represents calendar-based amounts; Duration represents elapsed time.
- The modern date-time value classes are immutable and thread-safe.
32. Conclusion
Optional and the Date-Time API are important features for writing reliable Java applications. Optional helps developers represent missing results and handle them deliberately, while the Date-Time API provides clear and robust tools for date calculations, formatting, parsing, and time-zone management.
By combining these features, developers can create programs that safely handle incomplete data and perform date-related operations with less boilerplate code. Practicing the examples and exercises in these notes will strengthen your Core Java knowledge and prepare you for coding assignments and technical interviews.
33. Additional Learning Resources