Java Tutorial » Chapter 17 — Date & Time

Chapter 17 — Java Date & Time

Mastering date and time manipulation in Java, from basic operations to advanced calendar management.

1. Introduction

Working with Date and Time in Java

Java provides several classes for working with dates and times. The original java.util.Date class, along with java.util.Calendar and java.text.SimpleDateFormat, have been part of Java since its early versions. In Java 8, a new Date and Time API was introduced in the java.time package, which offers a more comprehensive and immutable approach to handling dates and times.

In this chapter, we'll explore both the traditional and modern approaches to working with dates and times in Java, covering everything from getting the current date and time to complex date calculations and formatting.

2. Getting Current Date & Time

Retrieving the Current Date and Time

There are several ways to get the current date and time in Java, depending on which API you're using.

Using the Date Class (Traditional)

The Date class represents a specific moment in time, with millisecond precision.

import java.util.Date;

public class CurrentDateTime {
    public static void main(String[] args) {
        // Create a Date object with the current date and time
        Date currentDate = new Date();
        
        // Display the current date and time
        System.out.println("Current Date and Time: " + currentDate);
    }
}

Using the Java 8 Date and Time API (Modern)

The modern API provides more specific classes for different use cases:

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;

public class ModernDateTime {
    public static void main(String[] args) {
        // Current date
        LocalDate date = LocalDate.now();
        System.out.println("Current Date: " + date);
        
        // Current time
        LocalTime time = LocalTime.now();
        System.out.println("Current Time: " + time);
        
        // Current date and time
        LocalDateTime dateTime = LocalDateTime.now();
        System.out.println("Current Date and Time: " + dateTime);
    }
}
3. Date Comparison

Comparing Dates

Java provides several methods to compare dates, allowing you to determine which date is earlier, later, or if they are the same.

Using the Date Class

The Date class provides methods like before(), after(), and compareTo() for date comparison.

import java.util.Date;

public class DateComparison {
    public static void main(String[] args) {
        // Create two Date objects
        Date date1 = new Date(2023, 1, 1); // Note: Year is 1900 + year, month is 0-based
        Date date2 = new Date(2023, 1, 15);
        
        // Compare dates using before() and after()
        System.out.println("date1 before date2: " + date1.before(date2));
        System.out.println("date1 after date2: " + date1.after(date2));
        
        // Compare dates using compareTo()
        int result = date1.compareTo(date2);
        if (result < 0) {
            System.out.println("date1 is earlier than date2");
        } else if (result > 0) {
            System.out.println("date1 is later than date2");
        } else {
            System.out.println("date1 is equal to date2");
        }
    }
}

Using the Java 8 Date and Time API

The modern API provides isBefore(), isAfter(), and isEqual() methods for comparison.

import java.time.LocalDate;

public class ModernDateComparison {
    public static void main(String[] args) {
        // Create two LocalDate objects
        LocalDate date1 = LocalDate.of(2023, 1, 1);
        LocalDate date2 = LocalDate.of(2023, 1, 15);
        
        // Compare dates
        System.out.println("date1 before date2: " + date1.isBefore(date2));
        System.out.println("date1 after date2: " + date1.isAfter(date2));
        System.out.println("date1 equal to date2: " + date1.isEqual(date2));
    }
}
4. SimpleDateFormat Format Codes

Formatting Dates and Times

The SimpleDateFormat class allows you to format dates and times as strings according to specific patterns. Each pattern character represents a different part of the date or time.

Common Format Codes

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateFormatting {
    public static void main(String[] args) {
        Date currentDate = new Date();
        
        // Different date and time formats
        SimpleDateFormat format1 = new SimpleDateFormat("dd/MM/yyyy");
        SimpleDateFormat format2 = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
        SimpleDateFormat format3 = new SimpleDateFormat("EEE, MMM d, ''yy");
        SimpleDateFormat format4 = new SimpleDateFormat("h:mm a");
        
        System.out.println("Format 1: " + format1.format(currentDate));
        System.out.println("Format 2: " + format2.format(currentDate));
        System.out.println("Format 3: " + format3.format(currentDate));
        System.out.println("Format 4: " + format4.format(currentDate));
    }
}
5. Date & Time Conversion Characters

Understanding Format Characters

When formatting dates and times, you use specific characters to represent different components. Here are the most commonly used characters:

Character Description Example
yyyy Year (4-digit) 2023
MM Month (2-digit) 01, 12
dd Day of month (2-digit) 01, 31
HH Hour in day (0-23) 00, 23
mm Minute in hour 00, 59
ss Second in minute 00, 59
EEE Day name (abbreviated) Mon, Tue
MMMM Month name January, December
a AM/PM marker AM, PM
import java.text.SimpleDateFormat;
import java.util.Date;

public class FormatCharacters {
    public static void main(String[] args) {
        Date currentDate = new Date();
        
        // Using various format characters
        SimpleDateFormat format1 = new SimpleDateFormat("EEEE, MMMM dd, yyyy");
        SimpleDateFormat format2 = new SimpleDateFormat("hh:mm:ss a 'on' dd-MM-yyyy");
        SimpleDateFormat format3 = new SimpleDateFormat("'Week' w 'of' YYYY");
        
        System.out.println("Format 1: " + format1.format(currentDate));
        System.out.println("Format 2: " + format2.format(currentDate));
        System.out.println("Format 3: " + format3.format(currentDate));
    }
}
6. Parsing Strings into Dates

Converting Strings to Date Objects

The SimpleDateFormat class can also be used to parse strings into Date objects, as long as the string matches the specified pattern.

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateParsing {
    public static void main(String[] args) {
        // Define the date format
        SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
        
        try {
            // Parse a string into a Date object
            String dateString = "15-01-2023";
            Date date = format.parse(dateString);
            
            System.out.println("Original string: " + dateString);
            System.out.println("Parsed date: " + date);
            
            // Format the date back to a string with a different pattern
            SimpleDateFormat newFormat = new SimpleDateFormat("MMMM dd, yyyy");
            System.out.println("Formatted date: " + newFormat.format(date));
            
        } catch (ParseException e) {
            System.out.println("Error parsing date: " + e.getMessage());
        }
    }
}

Parsing with the Java 8 Date and Time API

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class ModernDateParsing {
    public static void main(String[] args) {
        // Define the date format
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
        
        // Parse a string into a LocalDate object
        String dateString = "15-01-2023";
        LocalDate date = LocalDate.parse(dateString, formatter);
        
        System.out.println("Original string: " + dateString);
        System.out.println("Parsed date: " + date);
        
        // Format the date back to a string with a different pattern
        DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("MMMM dd, yyyy");
        System.out.println("Formatted date: " + date.format(newFormatter));
    }
}
7. Sleeping for a While

Pausing Execution

Sometimes you need to pause the execution of your program for a specific amount of time. Java provides the Thread.sleep() method for this purpose.

import java.util.Date;

public class ThreadSleep {
    public static void main(String[] args) {
        try {
            System.out.println("Starting at: " + new Date());
            
            // Sleep for 3 seconds (3000 milliseconds)
            System.out.println("Sleeping for 3 seconds...");
            Thread.sleep(3000);
            
            System.out.println("Woke up at: " + new Date());
            
            // Sleep for 1.5 seconds (1500 milliseconds)
            System.out.println("Sleeping for 1.5 seconds...");
            Thread.sleep(1500);
            
            System.out.println("Woke up again at: " + new Date());
            
        } catch (InterruptedException e) {
            System.out.println("Thread was interrupted: " + e.getMessage());
        }
    }
}

Modern Alternative: Using TimeUnit

The TimeUnit enum provides a more readable way to specify sleep duration.

import java.util.Date;
import java.util.concurrent.TimeUnit;

public class TimeUnitSleep {
    public static void main(String[] args) {
        try {
            System.out.println("Starting at: " + new Date());
            
            // Sleep for 3 seconds
            System.out.println("Sleeping for 3 seconds...");
            TimeUnit.SECONDS.sleep(3);
            
            System.out.println("Woke up at: " + new Date());
            
            // Sleep for 500 milliseconds
            System.out.println("Sleeping for 500 milliseconds...");
            TimeUnit.MILLISECONDS.sleep(500);
            
            System.out.println("Woke up again at: " + new Date());
            
        } catch (InterruptedException e) {
            System.out.println("Thread was interrupted: " + e.getMessage());
        }
    }
}
8. Measuring Elapsed Time

Calculating Time Differences

Java provides several ways to measure elapsed time, which is useful for performance testing or timing operations.

Using System.currentTimeMillis()

public class ElapsedTime {
    public static void main(String[] args) {
        // Record the start time
        long startTime = System.currentTimeMillis();
        
        // Perform some operation
        long sum = 0;
        for (int i = 0; i < Integer.MAX_VALUE / 100; i++) {
            sum += i;
        }
        
        // Record the end time
        long endTime = System.currentTimeMillis();
        
        // Calculate and display the elapsed time
        long elapsedTime = endTime - startTime;
        System.out.println("Sum: " + sum);
        System.out.println("Elapsed time in milliseconds: " + elapsedTime);
        System.out.println("Elapsed time in seconds: " + elapsedTime / 1000.0);
    }
}

Using System.nanoTime()

For more precise measurements, especially for short durations, System.nanoTime() is preferred.

public class NanoTime {
    public static void main(String[] args) {
        // Record the start time
        long startTime = System.nanoTime();
        
        // Perform some operation
        long sum = 0;
        for (int i = 0; i < 1000000; i++) {
            sum += i;
        }
        
        // Record the end time
        long endTime = System.nanoTime();
        
        // Calculate and display the elapsed time
        long elapsedTime = endTime - startTime;
        System.out.println("Sum: " + sum);
        System.out.println("Elapsed time in nanoseconds: " + elapsedTime);
        System.out.println("Elapsed time in microseconds: " + elapsedTime / 1000.0);
        System.out.println("Elapsed time in milliseconds: " + elapsedTime / 1000000.0);
    }
}

Using the Java 8 Date and Time API

The modern API provides the Instant class for measuring time.

import java.time.Duration;
import java.time.Instant;

public class ModernElapsedTime {
    public static void main(String[] args) {
        // Record the start time
        Instant start = Instant.now();
        
        // Perform some operation
        long sum = 0;
        for (int i = 0; i < 1000000; i++) {
            sum += i;
        }
        
        // Record the end time
        Instant end = Instant.now();
        
        // Calculate and display the elapsed time
        Duration elapsed = Duration.between(start, end);
        System.out.println("Sum: " + sum);
        System.out.println("Elapsed time in milliseconds: " + elapsed.toMillis());
        System.out.println("Elapsed time in nanoseconds: " + elapsed.toNanos());
    }
}
9. GregorianCalendar Class

Advanced Calendar Operations

The GregorianCalendar class is a concrete implementation of the Calendar class that provides methods for manipulating dates and times. It's more flexible than the Date class for date calculations.

Creating and Using GregorianCalendar

import java.util.Calendar;
import java.util.GregorianCalendar;

public class GregorianCalendarExample {
    public static void main(String[] args) {
        // Create a GregorianCalendar with the current date and time
        GregorianCalendar calendar = new GregorianCalendar();
        
        // Get individual components of the date and time
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH); // 0-based (0 = January)
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);
        
        System.out.println("Current date and time:");
        System.out.println("Year: " + year);
        System.out.println("Month: " + (month + 1)); // Add 1 to display correctly
        System.out.println("Day: " + day);
        System.out.println("Hour: " + hour);
        System.out.println("Minute: " + minute);
        System.out.println("Second: " + second);
        
        // Check if it's a leap year
        boolean isLeapYear = calendar.isLeapYear(year);
        System.out.println("Is " + year + " a leap year? " + isLeapYear);
    }
}

Manipulating Dates

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;

public class CalendarManipulation {
    public static void main(String[] args) {
        // Create a GregorianCalendar for a specific date
        GregorianCalendar calendar = new GregorianCalendar(2023, 0, 15); // January 15, 2023
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        
        System.out.println("Original date: " + format.format(calendar.getTime()));
        
        // Add days
        calendar.add(Calendar.DAY_OF_MONTH, 10);
        System.out.println("After adding 10 days: " + format.format(calendar.getTime()));
        
        // Subtract months
        calendar.add(Calendar.MONTH, -2);
        System.out.println("After subtracting 2 months: " + format.format(calendar.getTime()));
        
        // Set a specific component
        calendar.set(Calendar.YEAR, 2024);
        System.out.println("After setting year to 2024: " + format.format(calendar.getTime()));
        
        // Get the maximum day of the current month
        int maxDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        System.out.println("Maximum day of the month: " + maxDay);
        
        // Get the day of the week
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        String[] dayNames = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
        System.out.println("Day of the week: " + dayNames[dayOfWeek - 1]);
    }
}

Converting Between Date and Calendar

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class DateCalendarConversion {
    public static void main(String[] args) {
        // Create a Date object
        Date date = new Date();
        System.out.println("Original Date: " + date);
        
        // Convert Date to Calendar
        GregorianCalendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        
        // Modify the Calendar
        calendar.add(Calendar.DAY_OF_MONTH, 7);
        
        // Convert Calendar back to Date
        Date newDate = calendar.getTime();
        System.out.println("Date after adding 7 days: " + newDate);
    }
}
10. Practice & Challenge

Test Your Skills

  1. Write a program that displays the current date in the format "Day, Month dd, yyyy" (e.g., "Monday, January 15, 2023").
  2. Write a program that calculates the number of days between two dates.
  3. Write a program that determines if a given year is a leap year.
  4. Write a program that adds a specific number of days, months, and years to a given date.
  5. Write a program that measures the execution time of a sorting algorithm on an array of random numbers.

🏆 Challenge: Age Calculator

Create a program that calculates a person's age in years, months, and days based on their birthdate and the current date. The program should also calculate the number of days until their next birthday.

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Scanner;

public class AgeCalculator {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        
        System.out.println("--- Age Calculator ---");
        System.out.print("Enter your birthdate (yyyy-MM-dd): ");
        String birthdateString = scanner.nextLine();
        
        try {
            // Parse the birthdate
            Date birthdate = format.parse(birthdateString);
            Calendar birthCalendar = new GregorianCalendar();
            birthCalendar.setTime(birthdate);
            
            // Get current date
            Calendar today = new GregorianCalendar();
            
            // Calculate age
            int years = today.get(Calendar.YEAR) - birthCalendar.get(Calendar.YEAR);
            int months = today.get(Calendar.MONTH) - birthCalendar.get(Calendar.MONTH);
            int days = today.get(Calendar.DAY_OF_MONTH) - birthCalendar.get(Calendar.DAY_OF_MONTH);
            
            // Adjust if necessary
            if (days < 0) {
                months--;
                // Get the maximum days in the previous month
                Calendar temp = (Calendar) today.clone();
                temp.add(Calendar.MONTH, -1);
                days += temp.getActualMaximum(Calendar.DAY_OF_MONTH);
            }
            
            if (months < 0) {
                years--;
                months += 12;
            }
            
            System.out.println("Your age is: " + years + " years, " + months + " months, and " + days + " days.");
            
            // Calculate days until next birthday
            Calendar nextBirthday = (Calendar) birthCalendar.clone();
            nextBirthday.set(Calendar.YEAR, today.get(Calendar.YEAR));
            
            // If birthday has passed this year, set it to next year
            if (nextBirthday.before(today)) {
                nextBirthday.add(Calendar.YEAR, 1);
            }
            
            // Calculate days until next birthday
            long millisecondsPerDay = 24 * 60 * 60 * 1000;
            long daysUntilBirthday = (nextBirthday.getTimeInMillis() - today.getTimeInMillis()) / millisecondsPerDay;
            
            System.out.println("Days until your next birthday: " + daysUntilBirthday);
            
        } catch (ParseException e) {
            System.out.println("Invalid date format. Please use yyyy-MM-dd.");
        }
        
        scanner.close();
    }
}