PYnative

Python Programming

  • Learn Python ▼
    • Python Tutorials
    • Python Basics
    • Python Interview Q&As
  • Exercises ▼
    • Python Exercises
    • C++ Exercises
    • C Programming Exercises
    • Java Exercises
  • Quizzes
  • Code Editor ▼
    • Online Python Code Editor
    • Online C Compiler
    • Online C++ Compiler
    • Online Java Compiler
Home » Java Exercises » Java Date and Time Exercises: 30 Coding Problems with Solutions

Java Date and Time Exercises: 30 Coding Problems with Solutions

Updated on: July 6, 2026 | Leave a Comment

This set of 30 Java Date and Time exercises covers the modern java.time API in depth, from basic date creation to time zone conversions.

You’ll work with LocalDate, LocalTime, LocalDateTime, and Instant, then move into date arithmetic (plusDays(), Period, ChronoUnit), TemporalAdjusters for things like “next Friday,” formatting and parsing with DateTimeFormatter, handling a DateTimeParseException, and finally ZonedDateTime and ZoneOffset for working across time zones.

Each exercise includes a Problem Statement, Purpose, Hint, and a Solution with Explanation that clarifies exactly which java.time class fits the problem and why.

  • Also, See: Java Exercises with over 20+ topic-wise sets and 575+ coding questions to practice.
  • Practice questions using our Online Java Compiler
+ Table of Contents (30 Exercises)

Table of contents

  • Exercise 1: Current Date Without Time
  • Exercise 2: Current Time Without Date
  • Exercise 3: Combining Date and Time
  • Exercise 4: Extracting Date Details
  • Exercise 5: Current Timestamp with Instant
  • Exercise 6: Midnight for the Current Date
  • Exercise 7: Two Weeks From Today
  • Exercise 8: Ten Days Before and After Today
  • Exercise 9: Adding Hours and Minutes to the Current Time
  • Exercise 10: Leap Year Checker
  • Exercise 11: Rolling a DateTime Backward
  • Exercise 12: Next and Previous Friday
  • Exercise 13: Days Between Two Dates
  • Exercise 14: Age Calculator with Period
  • Exercise 15: Remaining Months in the Year
  • Exercise 16: Time Difference with Duration
  • Exercise 17: Seconds Since the Unix Epoch
  • Exercise 18: Converting a Unix Timestamp
  • Exercise 19: Formatting a Date, European Style
  • Exercise 20: Formatting with a Descriptive Pattern
  • Exercise 21: Parsing a Date String
  • Exercise 22: Parsing a Date-Time with an Offset
  • Exercise 23: 24-Hour and 12-Hour Time Formats
  • Exercise 24: Handling a Malformed Date String
  • Exercise 25: Current Time in a Different Time Zone
  • Exercise 26: Listing Available Zone IDs
  • Exercise 27: Checking for Friday the 13th
  • Exercise 28: Listing All Mondays in a Month
  • Exercise 29: Month Lengths for a Given Year
  • Exercise 30: Time Difference Between Two Cities

Exercise 1: Current Date Without Time

Problem Statement: Write a program to display the current system date without the time component (LocalDate).

Purpose: This exercise introduces LocalDate, the java.time class dedicated purely to calendar dates, with no time or time zone information attached at all.

Given Input: none (the date is read directly from the system clock)

Expected Output (actual value depends on the date you run this on): Today's date: 2026-07-03

▼ Hint
  • Use the static factory method LocalDate.now() rather than a constructor, since LocalDate has no public constructors.
  • Printing a LocalDate directly automatically calls its toString(), which formats it as yyyy-MM-dd.
  • No time zone needs to be specified for a basic system-clock read, since now() uses the JVM’s default time zone automatically.
▼ Solution & Explanation
import java.time.LocalDate;

public class Main {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        System.out.println("Today's date: " + today);
    }
}Code language: Java (java)

Explanation:

  • LocalDate.now(): A static factory method that reads the system clock and returns today’s date in the JVM’s default time zone, with no time-of-day information at all.
  • LocalDate: Deliberately models only a calendar date, year, month, and day, which keeps it simple for use cases like birthdays or due dates that should never carry a time component.
  • Default formatting: Printing today directly relies on LocalDate‘s built-in toString(), which always produces the ISO-8601 yyyy-MM-dd format.
  • Alternative: LocalDate.now(ZoneId.of("America/New_York")) would return today’s date as seen in a specific time zone, rather than the JVM’s default one.

Exercise 2: Current Time Without Date

Problem Statement: Write a program to display the current system time without the date component (LocalTime).

Purpose: This exercise introduces LocalTime, the counterpart to LocalDate that models only a time of day, with no attached calendar date or time zone.

Given Input: none (the time is read directly from the system clock)

Expected Output (actual value depends on the moment you run this): Current time: 15:42:07.183451200

▼ Hint
  • Use the static factory method LocalTime.now().
  • The default toString() output includes hours, minutes, seconds, and often nanoseconds, depending on the precision the clock reports.
  • No date fields are involved at all, unlike LocalDateTime.
▼ Solution & Explanation
import java.time.LocalTime;

public class Main {
    public static void main(String[] args) {
        LocalTime now = LocalTime.now();
        System.out.println("Current time: " + now);
    }
}Code language: Java (java)

Explanation:

  • LocalTime.now(): Reads the system clock and returns the current time of day, in the JVM’s default time zone, with no date attached.
  • Precision: The exact number of digits shown after the seconds varies depending on how much sub-second precision the underlying system clock provides.
  • Why no date fields: LocalTime is intentionally limited to hour, minute, second, and nanosecond, making it suitable for representing something like a recurring daily alarm time that should not be tied to a specific calendar day.
  • Alternative: now.truncatedTo(ChronoUnit.SECONDS) would drop the nanosecond portion, producing a cleaner HH:mm:ss style output.

Exercise 3: Combining Date and Time

Problem Statement: Combine a specific local date (e.g., 2026-07-03) and a specific local time (e.g., 14:30:00) into a single LocalDateTime object.

Purpose: This exercise introduces LocalDateTime as the combination of LocalDate and LocalTime, useful whenever both the calendar date and the time of day matter together, such as scheduling an event.

Given Input: LocalDate.of(2026, 7, 3) and LocalTime.of(14, 30, 0)

Expected Output: Combined date-time: 2026-07-03T14:30

▼ Hint
  • Create the LocalDate and LocalTime separately with LocalDate.of() and LocalTime.of().
  • Use LocalDateTime.of(date, time) to merge the two into one object.
  • The printed format uses a T to separate the date portion from the time portion, following the ISO-8601 standard.
▼ Solution & Explanation
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class Main {
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2026, 7, 3);
        LocalTime time = LocalTime.of(14, 30, 0);
        LocalDateTime dateTime = LocalDateTime.of(date, time);

        System.out.println("Combined date-time: " + dateTime);
    }
}Code language: Java (java)

Explanation:

  • LocalDate.of(2026, 7, 3): Builds a specific calendar date directly from year, month, and day values, rather than reading the system clock.
  • LocalTime.of(14, 30, 0): Builds a specific time of day from hour, minute, and second values, using 24-hour notation.
  • LocalDateTime.of(date, time): Combines the two separate objects into a single LocalDateTime representing both the date and the time together.
  • Trailing seconds omitted: The printed output shows 14:30 rather than 14:30:00, since LocalDateTime‘s default formatting drops the seconds field whenever it is exactly zero.

Exercise 4: Extracting Date Details

Problem Statement: Extract individual details (Year, Month name, Day of the month, and Day of the week) from a given LocalDate object.

Purpose: This exercise practices pulling individual components out of a LocalDate, including converting the raw Month and DayOfWeek enum values into readable, full-word names.

Given Input: LocalDate.of(2026, 7, 3)

Expected Output:

Year: 2026
Month: July
Day of month: 3
Day of week: Friday
▼ Hint
  • Use getYear() and getDayOfMonth() for the two simple integer fields.
  • getMonth() and getDayOfWeek() return enum values, not strings, so printing them directly would show all-uppercase names like JULY.
  • Call getDisplayName(TextStyle.FULL, Locale.ENGLISH) on those enum values to get a properly capitalized, readable name instead.
▼ Solution & Explanation
import java.time.LocalDate;
import java.time.format.TextStyle;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2026, 7, 3);

        System.out.println("Year: " + date.getYear());
        System.out.println("Month: " + date.getMonth().getDisplayName(TextStyle.FULL, Locale.ENGLISH));
        System.out.println("Day of month: " + date.getDayOfMonth());
        System.out.println("Day of week: " + date.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.ENGLISH));
    }
}Code language: Java (java)

Explanation:

  • date.getYear() and date.getDayOfMonth(): Return plain int values for the year and day-of-month fields.
  • date.getMonth(): Returns a Month enum constant such as JULY, representing the month independently of any specific year or day.
  • getDisplayName(TextStyle.FULL, Locale.ENGLISH): Converts the enum constant into a properly formatted, human-readable name in the specified language, rather than the raw enum constant name.
  • date.getDayOfWeek(): Returns a DayOfWeek enum constant, calculated automatically from the date itself rather than being stored separately.

Exercise 5: Current Timestamp with Instant

Problem Statement: Get the current timestamp using Instant to represent the time in UTC/GMT.

Purpose: This exercise introduces Instant, which represents a single, unambiguous point on the timeline in UTC, independent of any time zone, making it ideal for timestamps like log entries or event records.

Given Input: none (the timestamp is read directly from the system clock)

Expected Output (actual value depends on the moment you run this): Current UTC timestamp: 2026-07-03T09:15:42.317842Z

▼ Hint
  • Use Instant.now() to capture the current moment in time.
  • Unlike LocalDate or LocalTime, Instant has no concept of a local time zone. It is always expressed in UTC.
  • The trailing Z in the printed output is the standard ISO-8601 marker meaning “UTC”.
▼ Solution & Explanation
import java.time.Instant;

public class Main {
    public static void main(String[] args) {
        Instant now = Instant.now();
        System.out.println("Current UTC timestamp: " + now);
    }
}Code language: Java (java)

Explanation:

  • Instant.now(): Returns the current point in time as measured from the epoch of January 1, 1970, UTC, expressed with nanosecond precision.
  • Always UTC: An Instant never carries a local time zone offset. It always represents the same universal moment, regardless of where the code is running.
  • Trailing Z: A standard ISO-8601 suffix indicating the timestamp is in UTC, sometimes referred to as “Zulu time”.
  • Why this matters: Instant is the preferred type for machine-to-machine timestamps, since it avoids all ambiguity around time zones and daylight saving changes that LocalDateTime alone would not resolve.

Exercise 6: Midnight for the Current Date

Problem Statement: Obtain the exact time at midnight (00:00) for the current date.

Purpose: This exercise introduces atStartOfDay(), a convenience method that produces the exact moment a calendar day begins, useful for range queries like “everything that happened today”.

Given Input: none (today’s date is read directly from the system clock)

Expected Output (actual value depends on the date you run this on): Midnight today: 2026-07-03T00:00

▼ Hint
  • Get today’s date first with LocalDate.now().
  • Call atStartOfDay() directly on that LocalDate, which returns a LocalDateTime with the time fields all set to zero.
  • This is a cleaner alternative to manually combining the date with LocalTime.MIDNIGHT.
▼ Solution & Explanation
import java.time.LocalDate;
import java.time.LocalDateTime;

public class Main {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        LocalDateTime midnight = today.atStartOfDay();

        System.out.println("Midnight today: " + midnight);
    }
}Code language: Java (java)

Explanation:

  • today.atStartOfDay(): Combines the given LocalDate with a time of exactly 00:00:00, returning a complete LocalDateTime.
  • Why not just use LocalTime.MIDNIGHT manually: atStartOfDay() exists as a convenience method specifically because, in time zones that observe daylight saving changes, the true start of a calendar day is not always exactly midnight local time. Using this method delegates that calculation correctly.
  • Alternative: today.atStartOfDay(ZoneId.of("America/New_York")) would return a ZonedDateTime, accounting for that specific zone’s actual start-of-day rules.

Exercise 7: Two Weeks From Today

Problem Statement: Write a program to calculate what the date will be exactly 2 weeks from today.

Purpose: This exercise introduces date arithmetic through plusWeeks(), one of several convenience methods LocalDate provides for adding a specific unit of time without any manual calendar math.

Given Input: today’s date, for example 2026-07-03

Expected Output (based on the example date above):

Today: 2026-07-03
Two weeks from today: 2026-07-17
▼ Hint
  • Get today’s date with LocalDate.now().
  • Call plusWeeks(2) on it, which correctly handles rolling over into the next month if needed.
  • LocalDate is immutable, so plusWeeks() returns a brand new object rather than modifying today itself.
▼ Solution & Explanation
import java.time.LocalDate;

public class Main {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        LocalDate twoWeeksLater = today.plusWeeks(2);

        System.out.println("Today: " + today);
        System.out.println("Two weeks from today: " + twoWeeksLater);
    }
}Code language: Java (java)

Explanation:

  • today.plusWeeks(2): Adds exactly 14 days to the date, automatically rolling over into the next month or year if the calculation crosses that boundary.
  • Immutability: plusWeeks() does not modify today in place. It returns a new LocalDate instance, which is why the result must be captured in its own variable.
  • Correct month rollover: Since 2026-07-03 plus 14 days lands on 2026-07-17, well within the same month in this example, but the same call handles crossing into August or beyond just as correctly without any extra logic.
  • Alternative: today.plusDays(14) would produce the exact same result, since a week is always defined as 7 days.

Exercise 8: Ten Days Before and After Today

Problem Statement: Calculate the exact date that occurred 10 days before today and the date that will occur 10 days after today.

Purpose: This exercise practices both directions of date arithmetic in the same program, using minusDays() and plusDays() side by side.

Given Input: today’s date, for example 2026-07-03

Expected Output (based on the example date above):

10 days before today: 2026-06-23
10 days after today: 2026-07-13
▼ Hint
  • Use minusDays(10) for the past date and plusDays(10) for the future date.
  • Both methods correctly cross month and year boundaries automatically, since they operate on the underlying calendar rather than doing simple digit arithmetic.
  • Call both methods on the same original today value, since it remains unchanged after each call.
▼ Solution & Explanation
import java.time.LocalDate;

public class Main {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        LocalDate tenDaysBefore = today.minusDays(10);
        LocalDate tenDaysAfter = today.plusDays(10);

        System.out.println("10 days before today: " + tenDaysBefore);
        System.out.println("10 days after today: " + tenDaysAfter);
    }
}Code language: Java (java)

Explanation:

  • today.minusDays(10): Subtracts 10 days from the date, automatically rolling back into the previous month if needed, as seen here where July 3rd minus 10 days lands in June.
  • today.plusDays(10): Adds 10 days forward, staying within the same month in this particular example.
  • Both derived from the same today: Since LocalDate is immutable, calling minusDays() and then plusDays() on the same original variable is safe. Neither call affects the value today itself holds.
  • Correct calendar awareness: These methods account for varying month lengths automatically, so the same logic works correctly near the end of February, April, or any other month without special-case code.

Exercise 9: Adding Hours and Minutes to the Current Time

Problem Statement: Add 5 hours and 30 minutes to the current system time and display the result.

Purpose: This exercise practices time arithmetic with LocalTime, and shows how chained plus...() calls combine cleanly since each one returns a new, updated LocalTime.

Given Input: none (the starting time is read directly from the system clock)

Expected Output (actual values depend on the moment you run this):

Current time: 10:15:22.418732600
Time after adding 5 hours 30 minutes: 15:45:22.418732600
▼ Hint
  • Get the current time with LocalTime.now().
  • Chain plusHours(5) and plusMinutes(30) together, since each call returns a new LocalTime that the next call can be applied to directly.
  • If the addition crosses midnight, LocalTime automatically wraps around back to 00:00 rather than producing an invalid hour value.
▼ Solution & Explanation
import java.time.LocalTime;

public class Main {
    public static void main(String[] args) {
        LocalTime now = LocalTime.now();
        LocalTime later = now.plusHours(5).plusMinutes(30);

        System.out.println("Current time: " + now);
        System.out.println("Time after adding 5 hours 30 minutes: " + later);
    }
}Code language: Java (java)

Explanation:

  • now.plusHours(5).plusMinutes(30): Chains two separate additions together, since plusHours() returns a new LocalTime that plusMinutes() is immediately called on.
  • Immutability: Neither plusHours() nor plusMinutes() changes now itself, which is why now still prints its original, unmodified value afterward.
  • Midnight wraparound: If the current time were, for example, 21:00, adding 5 hours 30 minutes would correctly wrap past midnight to 02:30 the next day, though LocalTime itself has no concept of which calendar day that lands on.
  • Alternative: now.plus(Duration.ofHours(5).plusMinutes(30)) achieves the same result using a Duration object instead of two chained method calls.

Exercise 10: Leap Year Checker

Problem Statement: Create a program that determines whether a user-inputted year is a leap year using the java.time API.

Purpose: This exercise shows that java.time already includes correct leap year logic built in, avoiding the need to hand-write the traditional divisible-by-4-but-not-100-unless-by-400 rule.

Given Input: year = 2024

Expected Output: 2024 is a leap year: true

▼ Hint
  • Read the year from the user with a Scanner.
  • Use the static method Year.isLeap(long year) rather than implementing the leap year rule manually.
  • The method returns a plain boolean, ready to print or use directly in further logic.
▼ Solution & Explanation
import java.time.Year;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter a year: ");
        int year = scanner.nextInt();

        boolean isLeap = Year.isLeap(year);
        System.out.println(year + " is a leap year: " + isLeap);
    }
}Code language: Java (java)

Explanation:

  • Year.isLeap(year): A static utility method that applies the full Gregorian leap year rule internally, correctly handling the divisible-by-4, not-divisible-by-100, divisible-by-400 exceptions.
  • scanner.nextInt(): Reads the year as an integer directly from user input, which is then passed straight into the leap year check.
  • 2024: Divisible by 4 and not divisible by 100, so it correctly qualifies as a leap year under the standard rule.
  • Alternative: LocalDate.of(year, 1, 1).isLeapYear() would produce the same result, since LocalDate also exposes an instance-level isLeapYear() method built on the same underlying rule.

Exercise 11: Rolling a DateTime Backward

Problem Statement: Roll a given LocalDateTime object backward by 3 years, 2 months, and 15 days.

Purpose: This exercise practices chaining several minus...() calls together on a single LocalDateTime, showing that mixed-unit date arithmetic is just a sequence of individual, well-defined steps.

Given Input: LocalDateTime.of(2026, 7, 3, 14, 30)

Expected Output:

Original: 2026-07-03T14:30
Rolled back: 2023-04-18T14:30
▼ Hint
  • Chain minusYears(), minusMonths(), and minusDays() together on the same object.
  • Each call returns a new LocalDateTime, so the next call in the chain applies to the already-adjusted result.
  • The order of the chained calls does not change the final result here, since years, months, and days are independent units.
▼ Solution & Explanation
import java.time.LocalDateTime;

public class Main {
    public static void main(String[] args) {
        LocalDateTime original = LocalDateTime.of(2026, 7, 3, 14, 30);

        LocalDateTime rolledBack = original.minusYears(3).minusMonths(2).minusDays(15);

        System.out.println("Original: " + original);
        System.out.println("Rolled back: " + rolledBack);
    }
}Code language: Java (java)

Explanation:

  • original.minusYears(3): Moves the date back to 2023-07-03T14:30, adjusting only the year field.
  • .minusMonths(2): Applied to that result, moving it back further to 2023-05-03T14:30.
  • .minusDays(15): Applied last, landing on 2023-04-18T14:30, the final rolled-back value.
  • Immutability: Each step in the chain produces a brand new LocalDateTime object rather than modifying the previous one, which is why original still prints its untouched starting value.

Exercise 12: Next and Previous Friday

Problem Statement: Find the date of the next and previous Friday relative to today’s date.

Purpose: This exercise introduces TemporalAdjusters, a set of reusable rules for calculations like “the next occurrence of a weekday” that would otherwise require manual day-of-week arithmetic.

Given Input: today’s date, for example 2026-07-03 (a Friday)

Expected Output (based on the example date above):

Today: 2026-07-03
Next Friday: 2026-07-10
Previous Friday: 2026-06-26
▼ Hint
  • Use TemporalAdjusters.next(DayOfWeek.FRIDAY) and TemporalAdjusters.previous(DayOfWeek.FRIDAY).
  • Apply an adjuster to a date using the with() method.
  • next() and previous() always move strictly forward or backward, even if today itself is already a Friday.
▼ Solution & Explanation
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;

public class Main {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();

        LocalDate nextFriday = today.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
        LocalDate previousFriday = today.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY));

        System.out.println("Today: " + today);
        System.out.println("Next Friday: " + nextFriday);
        System.out.println("Previous Friday: " + previousFriday);
    }
}Code language: Java (java)

Explanation:

  • TemporalAdjusters.next(DayOfWeek.FRIDAY): Produces a rule representing “the next Friday strictly after this date,” which is then applied with with().
  • Today already being a Friday: Since next() is strict, it skips today entirely and lands on the following week’s Friday, one week later, rather than returning today’s own date.
  • TemporalAdjusters.previous(DayOfWeek.FRIDAY): Works the same way in reverse, finding the most recent Friday strictly before today.
  • Alternative: TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY) and previousOrSame(...) would return today’s own date instead of skipping it, if today already matches the target day of week.

Exercise 13: Days Between Two Dates

Problem Statement: Calculate the exact number of days between two specific dates (e.g., your birthday and today).

Purpose: This exercise introduces ChronoUnit, which can measure the distance between two temporal objects in any unit, days in this case, without manual calendar math.

Given Input: birthday = LocalDate.of(1998, 11, 20), compared against today’s date

Expected Output (actual value depends on today’s date when you run this): Days since birthday: 10087

▼ Hint
  • Use ChronoUnit.DAYS.between(startDate, endDate) rather than subtracting the dates manually.
  • The argument order matters. Passing the earlier date first produces a positive result.
  • The result is returned as a long, since the day count can be very large for dates far apart.
▼ Solution & Explanation
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

public class Main {
    public static void main(String[] args) {
        LocalDate birthday = LocalDate.of(1998, 11, 20);
        LocalDate today = LocalDate.now();

        long daysBetween = ChronoUnit.DAYS.between(birthday, today);
        System.out.println("Days since birthday: " + daysBetween);
    }
}Code language: Java (java)

Explanation:

  • ChronoUnit.DAYS.between(birthday, today): Counts the exact number of whole days between the two dates, correctly accounting for every leap year that falls within the range.
  • Argument order: Passing birthday first and today second produces a positive count, since today comes after birthday. Swapping the order would return the same magnitude as a negative number.
  • Why not Period here: Period expresses a difference as separate years, months, and days, while ChronoUnit.DAYS.between() collapses the entire gap into one single, easily comparable number.
  • Alternative: The same calculation also works for other units by swapping DAYS for WEEKS, MONTHS, or YEARS, though those return the count truncated to whole units rather than the precise day count.

Exercise 14: Age Calculator with Period

Problem Statement: Write an age calculator program that accepts a birthdate and outputs the exact age in Years, Months, and Days using Period.

Purpose: This exercise introduces Period, which is specifically designed to break a date difference down into calendar-aware years, months, and days, unlike ChronoUnit, which only measures a single unit at a time.

Given Input: birthDate = LocalDate.of(1998, 11, 20), compared against today’s date

Expected Output (actual value depends on today’s date when you run this): Age: 27 years, 7 months, 13 days

▼ Hint
  • Use Period.between(birthDate, today) rather than ChronoUnit, since Period is the type designed to hold a years-months-days breakdown.
  • Call getYears(), getMonths(), and getDays() on the resulting Period to access each component.
  • The year count only increments once the birthday’s month and day have actually occurred in the current year, which Period handles automatically.
▼ Solution & Explanation
import java.time.LocalDate;
import java.time.Period;

public class Main {
    public static void main(String[] args) {
        LocalDate birthDate = LocalDate.of(1998, 11, 20);
        LocalDate today = LocalDate.now();

        Period age = Period.between(birthDate, today);

        System.out.println("Age: " + age.getYears() + " years, " + age.getMonths() + " months, " + age.getDays() + " days");
    }
}Code language: Java (java)

Explanation:

  • Period.between(birthDate, today): Calculates the calendar-aware difference between the two dates, expressed as whole years, whole remaining months, and whole remaining days.
  • Why the year count is 27, not 28: Since today falls in July and the birthday is in November, this year’s birthday has not occurred yet, so only 27 full years have actually passed.
  • age.getMonths() and age.getDays(): Represent the leftover time past the most recent full year, calculated the same way a person would count “years old, plus a few months and days” by hand.
  • Why not ChronoUnit.DAYS here: A single total day count would not distinguish “27 years and a bit” from any other combination of years, months, and days that add up to the same number of total days, which is exactly the breakdown this exercise asks for.

Exercise 15: Remaining Months in the Year

Problem Statement: Calculate the remaining months left in the current calendar year.

Purpose: This exercise practices reading the numeric month value from a date and using simple arithmetic against the fixed value 12 to figure out how much of the year remains.

Given Input: today’s date, for example 2026-07-03

Expected Output (based on the example date above):

Current month: JULY
Months remaining in 2026: 5
▼ Hint
  • Use getMonthValue() to get the current month as a plain int from 1 to 12.
  • Subtract that value from 12 to find how many months remain, including the possibility of 0 if it is already December.
  • Use getYear() to print which year the remaining month count applies to.
▼ Solution & Explanation
import java.time.LocalDate;
import java.time.Month;

public class Main {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        int currentMonth = today.getMonthValue();
        int remainingMonths = Month.DECEMBER.getValue() - currentMonth;

        System.out.println("Current month: " + today.getMonth());
        System.out.println("Months remaining in " + today.getYear() + ": " + remainingMonths);
    }
}Code language: Java (java)

Explanation:

  • today.getMonthValue(): Returns the current month as a plain integer, where January is 1 and December is 12.
  • Month.DECEMBER.getValue(): Returns 12, used here instead of a hardcoded literal to make the intent, “the last month of the year”, explicit in the code.
  • today.getMonth(): Printed directly, this shows the raw Month enum constant in all capitals, such as JULY, rather than a formatted display name.
  • Boundary case: If today fell in December, currentMonth would equal 12, making remainingMonths correctly evaluate to 0.

Exercise 16: Time Difference with Duration

Problem Statement: Compute the total difference between two LocalTime objects in Hours, Minutes, and Seconds using Duration.

Purpose: This exercise introduces Duration, the time-based counterpart to Period, used for measuring a span of time in hours, minutes, and seconds rather than years, months, and days.

Given Input: start = LocalTime.of(9, 15, 0), end = LocalTime.of(17, 45, 30)

Expected Output: Difference: 8 hours, 30 minutes, 30 seconds

▼ Hint
  • Use Duration.between(start, end) to get the total elapsed time as one combined object.
  • toHours() and toMinutes() return totals in that single unit, not a clean breakdown, so you will need the modulo operator % to isolate the leftover minutes and seconds.
  • getSeconds() returns the duration’s total length in seconds, useful for extracting the final seconds component with % 60.
▼ Solution & Explanation
import java.time.Duration;
import java.time.LocalTime;

public class Main {
    public static void main(String[] args) {
        LocalTime start = LocalTime.of(9, 15, 0);
        LocalTime end = LocalTime.of(17, 45, 30);

        Duration duration = Duration.between(start, end);

        long hours = duration.toHours();
        long minutes = duration.toMinutes() % 60;
        long seconds = duration.getSeconds() % 60;

        System.out.println("Difference: " + hours + " hours, " + minutes + " minutes, " + seconds + " seconds");
    }
}Code language: Java (java)

Explanation:

  • Duration.between(start, end): Captures the total elapsed time between the two LocalTime values as a single Duration object, internally stored as a total number of seconds and nanoseconds.
  • duration.toHours(): Returns the whole number of hours contained in the duration, truncating any leftover minutes or seconds.
  • duration.toMinutes() % 60: toMinutes() alone would return the total duration in minutes, 510 in this case, so the % 60 isolates just the leftover minutes beyond the full hours already counted.
  • duration.getSeconds() % 60: Similarly isolates the leftover seconds beyond the full minutes already accounted for.

Exercise 17: Seconds Since the Unix Epoch

Problem Statement: Find the total number of seconds that have elapsed since the Unix Epoch (January 1, 1970) up to the current moment.

Purpose: This exercise shows how Instant connects directly to the Unix timestamp format widely used in APIs, databases, and other programming languages.

Given Input: none (the current moment is read directly from the system clock)

Expected Output (actual value depends on the moment you run this): Seconds since Unix Epoch: 1783246542

▼ Hint
  • Get the current instant with Instant.now().
  • Call getEpochSecond() on it to retrieve the whole number of seconds since 1970-01-01T00:00:00Z.
  • This value only ever grows, and it is the same underlying timestamp format used across most systems and languages.
▼ Solution & Explanation
import java.time.Instant;

public class Main {
    public static void main(String[] args) {
        Instant now = Instant.now();
        long secondsSinceEpoch = now.getEpochSecond();

        System.out.println("Seconds since Unix Epoch: " + secondsSinceEpoch);
    }
}Code language: Java (java)

Explanation:

  • Instant.now(): Captures the current moment as an Instant, internally represented as a count of seconds and nanoseconds relative to the epoch.
  • now.getEpochSecond(): Extracts just the whole-seconds portion of that internal representation, discarding the nanosecond fraction.
  • Why this number is useful: A Unix timestamp is a single, unambiguous integer that is easy to store, compare, and transmit between systems, which is why so many APIs and databases use it as their default timestamp format.
  • Alternative: now.toEpochMilli() returns the same underlying value with millisecond precision instead, which is the format many JavaScript-based systems expect.

Exercise 18: Converting a Unix Timestamp

Problem Statement: Convert a raw Unix timestamp (e.g., 1719924800) back into a readable LocalDateTime.

Purpose: This exercise is the reverse of the previous one, showing how a raw numeric timestamp can be turned back into a structured, human-readable date and time.

Given Input: unixTimestamp = 1719924800L

Expected Output: Converted date-time: 2024-07-02T12:53:20

▼ Hint
  • Use Instant.ofEpochSecond(unixTimestamp) to turn the raw number back into an Instant.
  • An Instant alone has no notion of a calendar date or time zone, so it needs to be combined with one to produce a LocalDateTime.
  • Use LocalDateTime.ofInstant(instant, zoneId), passing ZoneId.of("UTC") to interpret the timestamp in UTC.
▼ Solution & Explanation
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;

public class Main {
    public static void main(String[] args) {
        long unixTimestamp = 1719924800L;

        LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(unixTimestamp), ZoneId.of("UTC"));

        System.out.println("Converted date-time: " + dateTime);
    }
}Code language: Java (java)

Explanation:

  • Instant.ofEpochSecond(unixTimestamp): Reconstructs the exact universal moment the raw number represents, the reverse operation of getEpochSecond() from the previous exercise.
  • ZoneId.of("UTC"): Specifies which time zone to interpret the instant in when converting it into calendar fields. Since Unix timestamps are inherently UTC-based, using UTC here keeps the conversion accurate.
  • LocalDateTime.ofInstant(instant, zoneId): Combines the universal instant with the chosen time zone to produce a readable calendar date and time.
  • Different zone, different result: Passing a different ZoneId, such as ZoneId.of("America/New_York"), would produce a different local date and time from the exact same underlying instant.

Exercise 19: Formatting a Date, European Style

Problem Statement: Format the current date into the standard European format: dd/MM/yyyy.

Purpose: This exercise introduces DateTimeFormatter, which controls how a date is rendered as text, independent of the default ISO format that printing a LocalDate directly produces.

Given Input: today’s date, for example 2026-07-03

Expected Output (based on the example date above): Formatted date: 03/07/2026

▼ Hint
  • Build a DateTimeFormatter with DateTimeFormatter.ofPattern("dd/MM/yyyy").
  • Lowercase dd and yyyy represent day and year, while uppercase MM represents month, since lowercase mm would mean minutes instead.
  • Call format() on the LocalDate, passing in the formatter, to get the styled string.
▼ Solution & Explanation
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");

        String formatted = today.format(formatter);
        System.out.println("Formatted date: " + formatted);
    }
}Code language: Java (java)

Explanation:

  • DateTimeFormatter.ofPattern("dd/MM/yyyy"): Defines a custom text layout using pattern letters, where dd is the zero-padded day, MM is the zero-padded month, and yyyy is the four-digit year.
  • Case sensitivity matters: MM (uppercase) means month, while mm (lowercase) means minutes. Mixing these up is a common source of formatting bugs.
  • today.format(formatter): Applies the pattern to the date, producing a plain String laid out exactly according to the formatter’s rules.
  • Reusability: The same formatter instance can be reused to format any number of different LocalDate values consistently, rather than building a new formatter each time.

Exercise 20: Formatting with a Descriptive Pattern

Problem Statement: Print the current date and time using a descriptive textual pattern, for example: Friday, 03 July 2026 03:45 PM.

Purpose: This exercise builds on the previous one with a richer pattern, combining full weekday and month names with a 12-hour clock and an AM/PM marker.

Given Input: the current date and time, for example 2026-07-03T15:45

Expected Output (based on the example date and time above): Formatted: Friday, 03 July 2026 03:45 PM

▼ Hint
  • Use EEEE for the full weekday name and MMMM for the full month name.
  • Use lowercase hh for the 12-hour clock hour, paired with a literal a for the AM/PM marker.
  • Pass a Locale, such as Locale.ENGLISH, to the formatter to guarantee the weekday and month names render in English regardless of the system’s default locale.
▼ Solution & Explanation
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE, dd MMMM yyyy hh:mm a", Locale.ENGLISH);

        String formatted = now.format(formatter);
        System.out.println("Formatted: " + formatted);
    }
}Code language: Java (java)

Explanation:

  • EEEE: Renders the full weekday name, such as Friday, rather than an abbreviation like Fri.
  • MMMM: Renders the full month name, such as July, following the same full-versus-abbreviated pattern convention as the weekday.
  • hh:mm a: hh is the 12-hour clock hour, mm is minutes, and the literal a inserts the localized AM or PM marker at the end.
  • Locale.ENGLISH: Forces the weekday and month names to render in English, so the output stays consistent even if this code runs on a system configured with a different default locale.

Exercise 21: Parsing a Date String

Problem Statement: Convert a string representing a date (e.g., "2026-12-25") into a LocalDate object using DateTimeFormatter.

Purpose: This exercise introduces parsing, the reverse of formatting, where a plain text string is converted back into a structured LocalDate object that supports date arithmetic and comparisons.

Given Input: dateString = "2026-12-25"

Expected Output: Parsed date: 2026-12-25

▼ Hint
  • Build a DateTimeFormatter matching the exact layout of the input string, such as "yyyy-MM-dd".
  • Call the static method LocalDate.parse(text, formatter), passing both the string and the formatter.
  • The resulting object is a genuine LocalDate, not just a validated string, so it immediately supports methods like plusDays() or getDayOfWeek().
▼ Solution & Explanation
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        String dateString = "2026-12-25";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        LocalDate date = LocalDate.parse(dateString, formatter);
        System.out.println("Parsed date: " + date);
    }
}Code language: Java (java)

Explanation:

  • DateTimeFormatter.ofPattern("yyyy-MM-dd"): Describes the exact shape the input text must follow in order to be parsed successfully.
  • LocalDate.parse(dateString, formatter): Reads the string according to that pattern and constructs a real LocalDate object from it.
  • Result type: Once parsed, date behaves exactly like any other LocalDate, whether it was built from a string, from now(), or from LocalDate.of().
  • Alternative: Since "2026-12-25" already matches the default ISO-8601 format, LocalDate.parse(dateString) without any formatter would also work here. An explicit formatter becomes necessary once the input string uses a non-standard layout.

Exercise 22: Parsing a Date-Time with an Offset

Problem Statement: Parse a complex date-time string containing a text layout (e.g., "2026-07-03T15:30:00-05:00") into a proper Java object.

Purpose: This exercise introduces OffsetDateTime, used when a date-time string includes a fixed UTC offset, information that a plain LocalDateTime would simply discard.

Given Input: dateTimeString = "2026-07-03T15:30:00-05:00"

Expected Output:

Parsed: 2026-07-03T15:30-05:00
Offset: -05:00
▼ Hint
  • Use OffsetDateTime rather than LocalDateTime, since the string includes a UTC offset that needs somewhere to live.
  • Since this string already matches the standard ISO-8601 offset format, OffsetDateTime.parse(text) works directly without needing a custom DateTimeFormatter.
  • Call getOffset() on the result to access the parsed offset on its own.
▼ Solution & Explanation
import java.time.OffsetDateTime;

public class Main {
    public static void main(String[] args) {
        String dateTimeString = "2026-07-03T15:30:00-05:00";

        OffsetDateTime offsetDateTime = OffsetDateTime.parse(dateTimeString);
        System.out.println("Parsed: " + offsetDateTime);
        System.out.println("Offset: " + offsetDateTime.getOffset());
    }
}Code language: Java (java)

Explanation:

  • OffsetDateTime.parse(dateTimeString): Parses both the local date-time portion and the trailing -05:00 offset in one step, since the string already follows the default ISO-8601 layout OffsetDateTime expects.
  • Why not LocalDateTime: Parsing this same string as a LocalDateTime would fail, since LocalDateTime has no field to hold the offset information at the end of the string.
  • offsetDateTime.getOffset(): Extracts just the -05:00 portion as a standalone ZoneOffset object, separate from the date and time fields.
  • Seconds dropped in output: The printed result shows 15:30 rather than 15:30:00, since the default formatting omits the seconds field whenever it is exactly zero, the same behavior seen with LocalDateTime.

Exercise 23: 24-Hour and 12-Hour Time Formats

Problem Statement: Print the current time in a strict 24-hour format (HH:mm:ss) and a localized 12-hour AM/PM format.

Purpose: This exercise practices formatting the same underlying time in two different, commonly requested layouts by building and applying two separate DateTimeFormatter instances.

Given Input: none (the current time is read directly from the system clock)

Expected Output (actual values depend on the moment you run this):

24-hour format: 15:45:22
12-hour format: 03:45:22 PM
▼ Hint
  • Uppercase HH represents the 24-hour clock hour, from 00 to 23.
  • Lowercase hh represents the 12-hour clock hour, from 01 to 12, and needs a trailing a pattern letter to show AM or PM.
  • Build two separate DateTimeFormatter instances, one for each pattern, and apply both to the same LocalTime.
▼ Solution & Explanation
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        LocalTime now = LocalTime.now();

        DateTimeFormatter military = DateTimeFormatter.ofPattern("HH:mm:ss");
        DateTimeFormatter standard = DateTimeFormatter.ofPattern("hh:mm:ss a", Locale.ENGLISH);

        System.out.println("24-hour format: " + now.format(military));
        System.out.println("12-hour format: " + now.format(standard));
    }
}Code language: Java (java)

Explanation:

  • "HH:mm:ss": Uses the 24-hour hour field, so 3:45 PM prints as 15:45:22 with no AM/PM marker needed.
  • "hh:mm:ss a": Uses the 12-hour hour field paired with the a marker, so the same moment prints as 03:45:22 PM instead.
  • Same underlying now, two formatters: Both formatted strings describe the exact same point in time, just laid out according to two different pattern rules.
  • Locale.ENGLISH: Ensures the AM/PM marker renders in English, since some locales use different text or symbols for that marker.

Exercise 24: Handling a Malformed Date String

Problem Statement: Write a program to safely handle and parse a malformed date string by catching the appropriate exception (DateTimeParseException).

Purpose: This exercise introduces DateTimeParseException, the specific unchecked exception thrown when a string does not match the expected pattern or contains an invalid calendar value.

Given Input: badDateString = "2026-13-40" (month 13 and day 40 do not exist)

Expected Output: Error: Invalid date format - Text '2026-13-40' could not be parsed: Invalid value for MonthOfYear (valid values 1 - 12): 13

▼ Hint
  • Wrap the LocalDate.parse() call in a try-catch block.
  • DateTimeParseException is unchecked, but catching it explicitly still lets you handle bad input gracefully instead of letting the program crash.
  • Use e.getMessage() to see exactly which part of the string failed and why.
▼ Solution & Explanation
import java.time.LocalDate;
import java.time.format.DateTimeParseException;

public class Main {
    public static void main(String[] args) {
        String badDateString = "2026-13-40";

        try {
            LocalDate date = LocalDate.parse(badDateString);
            System.out.println("Parsed date: " + date);
        } catch (DateTimeParseException e) {
            System.out.println("Error: Invalid date format - " + e.getMessage());
        }
    }
}Code language: Java (java)

Explanation:

  • LocalDate.parse(badDateString): Attempts to interpret "2026-13-40" as an ISO date, but fails as soon as it validates the month field.
  • DateTimeParseException: Thrown specifically for parsing failures, distinct from other exceptions, making it easy to catch parsing problems without accidentally catching unrelated bugs.
  • Why month fails first: The parser validates each field as it goes, so it reports the invalid month value 13 immediately, without ever getting to check whether day 40 would have been valid too.
  • e.getMessage(): Returns a detailed, specific explanation of exactly what went wrong and where, which is far more useful for debugging than a generic failure message.

Exercise 25: Current Time in a Different Time Zone

Problem Statement: Get the current time in a completely different time zone (e.g., "America/New_York" or "Europe/London") using ZonedDateTime.

Purpose: This exercise introduces ZonedDateTime, which carries full time zone rules, including daylight saving transitions, unlike OffsetDateTime, which only stores a fixed offset.

Given Input: none (the current moment is read directly from the system clock)

Expected Output (actual values depend on the moment you run this):

New York time: 2026-07-03T06:15:22.418732-04:00[America/New_York]
London time: 2026-07-03T11:15:22.418732+01:00[Europe/London]
▼ Hint
  • Use ZonedDateTime.now(zoneId), passing a ZoneId built from a region string like "America/New_York".
  • Each call to now(zoneId) reads the same underlying instant, just displayed according to that specific zone’s rules.
  • The printed offset can differ between zones and can even change for the same zone depending on daylight saving time.
▼ Solution & Explanation
import java.time.ZonedDateTime;
import java.time.ZoneId;

public class Main {
    public static void main(String[] args) {
        ZonedDateTime newYorkTime = ZonedDateTime.now(ZoneId.of("America/New_York"));
        ZonedDateTime londonTime = ZonedDateTime.now(ZoneId.of("Europe/London"));

        System.out.println("New York time: " + newYorkTime);
        System.out.println("London time: " + londonTime);
    }
}Code language: Java (java)

Explanation:

  • ZoneId.of("America/New_York"): Represents a named geographic region with its own complete set of historical and current offset rules, including daylight saving transitions.
  • ZonedDateTime.now(zoneId): Captures the current instant and immediately renders it in local date and time fields for that specific zone.
  • Bracketed zone name in output: The trailing [America/New_York] in the printed result distinguishes a ZonedDateTime from an OffsetDateTime, showing which named zone’s rules were actually applied.
  • Why the offsets differ: Both lines represent the exact same real-world moment, but America/New_York and Europe/London have different UTC offsets, so their local time-of-day fields naturally differ too.

Exercise 26: Listing Available Zone IDs

Problem Statement: Print a list of all available zone IDs supported by the system using ZoneId.getAvailableZoneIds().

Purpose: This exercise shows how to discover every valid zone name the JVM recognizes, useful when building a dropdown of selectable time zones or validating user input against real zone names.

Given Input: none

Expected Output (the exact count and first entries can vary slightly by JDK version):

Total available zone IDs: 601
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
▼ Hint
  • ZoneId.getAvailableZoneIds() returns a Set<String>, so the entries have no guaranteed order on their own.
  • Use size() to report the total count directly from the set.
  • Sort the set with a stream before printing a small sample, so the output is at least consistent and readable across runs.
▼ Solution & Explanation
import java.time.ZoneId;
import java.util.Set;

public class Main {
    public static void main(String[] args) {
        Set<String> zoneIds = ZoneId.getAvailableZoneIds();
        System.out.println("Total available zone IDs: " + zoneIds.size());

        zoneIds.stream()
               .sorted()
               .limit(5)
               .forEach(System.out::println);
    }
}Code language: Java (java)

Explanation:

  • ZoneId.getAvailableZoneIds(): Returns every zone name the JVM currently recognizes, sourced from its built-in copy of the IANA time zone database.
  • zoneIds.size(): Reports the total number of recognized zone names, which changes slightly between JDK releases as the underlying time zone database is updated.
  • .sorted(): Since a Set has no inherent order, sorting the stream alphabetically before printing makes the sample output predictable and easy to read.
  • .limit(5): Restricts the printed sample to just the first five entries alphabetically, since printing all several hundred zone names at once would be excessive for a simple demonstration.

Exercise 27: Checking for Friday the 13th

Problem Statement: Write a program to check if a specific date falls on an infamous “Friday the 13th”.

Purpose: This exercise combines two separate checks on the same date, the day-of-month value and the day-of-week value, into a single boolean condition.

Given Input: LocalDate.of(2026, 2, 13)

Expected Output: 2026-02-13 is Friday the 13th: true

▼ Hint
  • Use getDayOfMonth() to check whether the date falls on the 13th.
  • Use getDayOfWeek() compared against the DayOfWeek.FRIDAY enum constant to check the weekday.
  • Combine both checks with &&, since both conditions must be true at once.
▼ Solution & Explanation
import java.time.DayOfWeek;
import java.time.LocalDate;

public class Main {
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2026, 2, 13);

        boolean isFridayThe13th = date.getDayOfMonth() == 13 && date.getDayOfWeek() == DayOfWeek.FRIDAY;

        System.out.println(date + " is Friday the 13th: " + isFridayThe13th);
    }
}Code language: Java (java)

Explanation:

  • date.getDayOfMonth() == 13: Checks the numeric day-of-month field directly against the literal value 13.
  • date.getDayOfWeek() == DayOfWeek.FRIDAY: Compares the computed weekday enum constant against FRIDAY, using == since enum constants are singleton instances that can be compared safely this way.
  • &&: Requires both conditions to hold simultaneously, since a date could be the 13th on a different weekday, or a Friday on a different day of the month, without qualifying.
  • LocalDate.of(2026, 2, 13): This particular date does land on a Friday, so both conditions are satisfied and the result is true.

Exercise 28: Listing All Mondays in a Month

Problem Statement: Given a year and a month, write a program that lists all the Mondays that occur during that specific month.

Purpose: This exercise combines YearMonth with a day-by-day scanning loop, showing how to walk through every date in a given month and filter for a specific weekday.

Given Input: year = 2026, month = 7 (July)

Expected Output:

Mondays in 2026-07:
2026-07-06
2026-07-13
2026-07-20
2026-07-27
▼ Hint
  • Use YearMonth.of(year, month) to represent the target month, and call atDay(1) to get its first date.
  • Loop day by day using plusDays(1), stopping once getMonthValue() no longer matches the target month.
  • Inside the loop, check getDayOfWeek() == DayOfWeek.MONDAY before printing each date.
▼ Solution & Explanation
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.YearMonth;

public class Main {
    public static void main(String[] args) {
        int year = 2026;
        int month = 7;

        YearMonth yearMonth = YearMonth.of(year, month);
        LocalDate date = yearMonth.atDay(1);

        System.out.println("Mondays in " + yearMonth + ":");
        while (date.getMonthValue() == month) {
            if (date.getDayOfWeek() == DayOfWeek.MONDAY) {
                System.out.println(date);
            }
            date = date.plusDays(1);
        }
    }
}Code language: Java (java)

Explanation:

  • YearMonth.of(year, month): Represents a specific month without needing a particular day, useful as an anchor for month-wide calculations like this one.
  • yearMonth.atDay(1): Produces the first calendar date of that month, used here as the starting point for the scan.
  • while (date.getMonthValue() == month): Keeps the loop going only while date is still within the target month, naturally stopping once it rolls over into the next one.
  • date.plusDays(1): Advances the scan one day at a time, checking every single date in the month for a match against DayOfWeek.MONDAY.

Exercise 29: Month Lengths for a Given Year

Problem Statement: Calculate the length (total days) of every single month for a given year to account for leap years automatically.

Purpose: This exercise loops over the Month enum’s built-in values and uses lengthOfMonth(), which already factors in leap years, rather than hardcoding month lengths manually.

Given Input: year = 2028 (a leap year)

Expected Output:

JANUARY: 31 days
FEBRUARY: 29 days
MARCH: 31 days
APRIL: 30 days
MAY: 31 days
JUNE: 30 days
JULY: 31 days
AUGUST: 31 days
SEPTEMBER: 30 days
OCTOBER: 31 days
NOVEMBER: 30 days
DECEMBER: 31 days
▼ Hint
  • Loop over Month.values(), which gives every month constant in calendar order.
  • For each month, build a LocalDate using that month and the target year, with the day set to 1.
  • Call lengthOfMonth() on that date, which returns how many days the month actually has, correctly adjusting February for leap years.
▼ Solution & Explanation
import java.time.LocalDate;
import java.time.Month;

public class Main {
    public static void main(String[] args) {
        int year = 2028;

        for (Month month : Month.values()) {
            int length = LocalDate.of(year, month, 1).lengthOfMonth();
            System.out.println(month + ": " + length + " days");
        }
    }
}Code language: Java (java)

Explanation:

  • Month.values(): Returns all twelve Month enum constants in calendar order, from JANUARY through DECEMBER, ready to loop over directly.
  • LocalDate.of(year, month, 1): Builds a date on the first of each month for the target year. The day value itself does not affect the resulting month length, only the year and month do.
  • lengthOfMonth(): Returns the correct number of days for that specific month and year, automatically returning 29 for February in a leap year and 28 otherwise.
  • 2028 as a leap year: Since 2028 is divisible by 4 and not by 100, February correctly reports 29 days in the output, confirming the leap year logic is applied automatically.

Exercise 30: Time Difference Between Two Cities

Problem Statement: Find the exact time difference (in hours) between two different cities at the current moment (e.g., the offset difference between Tokyo and Chicago).

Purpose: This closing exercise combines ZonedDateTime with ZoneOffset arithmetic, showing how to compute a live difference between two zones that correctly accounts for daylight saving time on either side.

Given Input: none (both times are read from the system clock, in their respective zones)

Expected Output (actual clock values depend on the moment you run this, though the hour difference stays stable across most of the year):

Tokyo time: 2026-07-04T05:15:22.418732+09:00[Asia/Tokyo]
Chicago time: 2026-07-03T15:15:22.418732-05:00[America/Chicago]
Difference: 14 hours
▼ Hint
  • Get the current ZonedDateTime for each city separately, using ZoneId.of("Asia/Tokyo") and ZoneId.of("America/Chicago").
  • Call getOffset() on each to retrieve its current ZoneOffset, which reflects any active daylight saving adjustment.
  • Use getTotalSeconds() on each offset, subtract them, and divide by 3600 to convert the difference into whole hours.
▼ Solution & Explanation
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        ZonedDateTime tokyoTime = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
        ZonedDateTime chicagoTime = ZonedDateTime.now(ZoneId.of("America/Chicago"));

        ZoneOffset tokyoOffset = tokyoTime.getOffset();
        ZoneOffset chicagoOffset = chicagoTime.getOffset();

        int differenceInSeconds = tokyoOffset.getTotalSeconds() - chicagoOffset.getTotalSeconds();
        int differenceInHours = differenceInSeconds / 3600;

        System.out.println("Tokyo time: " + tokyoTime);
        System.out.println("Chicago time: " + chicagoTime);
        System.out.println("Difference: " + differenceInHours + " hours");
    }
}Code language: Java (java)

Explanation:

  • ZonedDateTime.now(ZoneId.of(...)): Captures the current moment as seen locally in each named zone, including whichever offset is currently active for that location.
  • getOffset(): Retrieves just the current UTC offset for that zone, such as +09:00 for Tokyo, which does not observe daylight saving, or -05:00 for Chicago during its daylight saving period.
  • tokyoOffset.getTotalSeconds() - chicagoOffset.getTotalSeconds(): Subtracts the two offsets, measured in total seconds, giving the raw difference before converting to a more readable unit.
  • differenceInSeconds / 3600: Converts the raw second difference into whole hours, producing the final, easily understood hour gap between the two cities.

Filed Under: Java Exercises

Did you find this page helpful? Let others know about it. Sharing helps me continue to create free Python resources.

TweetF  sharein  shareP  Pin

About Vishal

I’m Vishal Hule, the Founder of PYnative.com. As a Python developer, I enjoy assisting students, developers, and learners. Follow me on Twitter.

Related Tutorial Topics:

Java Exercises

All Coding Exercises:

C Exercises
C++ Exercises
Python Exercises
Java Exercises

Python Exercises and Quizzes

Free coding exercises and quizzes cover Python basics, data structure, data analytics, and more.

  • 15+ Topic-specific Exercises and Quizzes
  • Each Exercise contains 25+ questions
  • Each Quiz contains 25 MCQ
Exercises
Quizzes

Leave a Reply Cancel reply

your email address will NOT be published. all comments are moderated according to our comment policy.

Use <pre> tag for posting code. E.g. <pre> Your entire code </pre>

In: Java Exercises
TweetF  sharein  shareP  Pin

  Java Exercises

  • All Java Exercises
  • Java Exercise for Beginners
  • Java Loops Exercise
  • Java String Exercise
  • Java ArrayList Exercise
  • Java LinkedList Exercise
  • Java HashMap and TreeMap Exercise
  • Java HashSet and TreeSet Exercise
  • Java OOP Exercise
  • Java Methods Exercise
  • Java Enums Exercise
  • Java Exception Handling Exercise
  • Java File Handling Exercise
  • Java Date and Time Exercise
  • Java Data Structures Exercise
  • Java Sorting and Searching Exercise
  • Java Lambda and Functional Interfaces Exercise
  • Java Regex Exercise
  • Java Random Data Generation Exercise
  • Java Generics Exercise
  • Java Reflection Exercise
  • Java JDBC Exercise

All Coding Exercises

Python Exercises C Exercises C++ Exercises Java Exercises

About PYnative

PYnative.com is for Python lovers. Here, You can get Tutorials, Exercises, and Quizzes to practice and improve your Python skills.

Follow Us

To get New Python Tutorials, Exercises, and Quizzes

  • Twitter
  • Facebook
  • Sitemap

Explore Python

  • Learn Python
  • Python Basics
  • Python Databases
  • Python Exercises
  • Python Quizzes
  • Online Python Code Editor
  • Python Tricks

Coding Exercises

  • C Exercises
  • C++ Exercises
  • Python Exercises
  • Java Exercises

Legal Stuff

  • About Us
  • Contact Us

We use cookies to improve your experience. While using PYnative, you agree to have read and accepted our:

  • Terms Of Use
  • Privacy Policy
  • Cookie Policy

Copyright © 2018–2026 pynative.com