Date & Time API — java.time

Java 8-এর সেই API যা তারিখ-সময় অবশেষে ঠিক করে দিয়েছে

Read: ~28 min Intermediate 5 practice problems Live code runner

1. Forget Date and Calendar

For two decades Java's date/time story was a disaster: java.util.Date was mutable, months started at zero, timezones leaked everywhere, and Calendar was worse. Java 8 finally fixed it with the java.time package — immutable, thread-safe, and modeled on the superb Joda-Time library. Everything you write from now on should use java.time.

দুই দশক Java-র date/time ভয়ঙ্কর ছিল — java.util.Date mutable, মাস ০ থেকে শুরু, timezone সব জায়গায় ছড়িয়ে। Java 8-এ java.time এসে সব ঠিক করে দিল — immutable, thread-safe। নতুন কোডে সবসময় এটাই ব্যবহার করুন।
Rule: never use new Date(), SimpleDateFormat, or Calendar in new code. They will pass code review somewhere eventually; they should never pass yours.

2. The Six Core Types

java.time has many classes, but six carry 95% of the weight. Pick the one that matches the meaning of what you are storing, not the one that happens to be convenient.

java.time-এ অনেক class থাকলেও ৬টিই প্রধান। আপনি যা সংরক্ষণ করছেন সেই অর্থ অনুযায়ী class বেছে নিন — সুবিধার জন্য নয়।
TypeRepresentsবাংলায়
LocalDateA date without time or zone — 2025-04-18.শুধু তারিখ — সময় বা zone নেই।
LocalTimeA time without date or zone — 13:45:30.শুধু সময় — তারিখ বা zone নেই।
LocalDateTimeDate + time, still no zone.তারিখ + সময়, zone নেই।
ZonedDateTimeDate + time + timezone — the real-world wall clock.তারিখ + সময় + timezone।
InstantA moment in time — seconds since 1970 UTC.UTC moment — Unix epoch থেকে গণনা।
Duration / PeriodMachine-time gap / human-time gap.সময়ের ব্যবধান — sec বনাম বছর-মাস।
Which type for which meaning? LocalDate birthday, invoice date LocalTime shop open 09:00 LocalDateTime event @ 2025-04-18 13:00 ZonedDateTime meeting across zones Instant log timestamp (UTC) Duration 2h 30m elapsed Period 2 years, 3 months Figure 34.1 — কোন type কখন।

3. Hello LocalDate / LocalTime / LocalDateTime

Every type has a now() factory, an of(...) factory, and a parse(String) factory. Once you have an instance, it is immutable — every modification returns a new object.

প্রতিটি type-এ তিনটি factory — now(), of(...) এবং parse(String)। instance তৈরি হলে সেটি immutable — যেকোনো পরিবর্তন নতুন object ফেরত দেয়।
Main.java
import java.time.*;

class Main {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        LocalDate bday  = LocalDate.of(1995, 5, 23);

        LocalTime now    = LocalTime.now();
        LocalDateTime meeting = LocalDateTime.of(2025, 4, 18, 14, 30);

        System.out.println("today     = " + today);
        System.out.println("birthday  = " + bday);
        System.out.println("time now  = " + now);
        System.out.println("meeting   = " + meeting);

        // modification returns a NEW object — the original is unchanged
        LocalDate nextWeek = today.plusDays(7);
        System.out.println("next week = " + nextWeek);
        System.out.println("still today = " + today);
    }
}

4. Timezones — ZonedDateTime and Instant

When a meeting is scheduled at "Dhaka 14:00" on April 18, a user in London sees it at 08:00 (or 09:00 depending on British Summer Time). That conversion is precisely what ZonedDateTime exists for. Under the hood, an Instant is simply a count of seconds since 1970-01-01 UTC — the universal moment.

ঢাকা 14:00-এ meeting হলে London-এর user 08:00 (বা 09:00, daylight-saving-এর উপর নির্ভর করে) দেখেন। এই conversion-এর জন্যই ZonedDateTime। ভেতরে Instant = 1970 UTC থেকে সেকেন্ডের সংখ্যা — universal moment।
Main.java
import java.time.*;

class Main {
    public static void main(String[] args) {
        ZonedDateTime dhaka = ZonedDateTime.of(
            2025, 4, 18, 14, 0, 0, 0,
            ZoneId.of("Asia/Dhaka"));

        ZonedDateTime london = dhaka.withZoneSameInstant(ZoneId.of("Europe/London"));
        ZonedDateTime tokyo  = dhaka.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));

        System.out.println("Dhaka  : " + dhaka);
        System.out.println("London : " + london);
        System.out.println("Tokyo  : " + tokyo);

        // the same moment in UTC (as an Instant)
        System.out.println("UTC instant = " + dhaka.toInstant());
    }
}

5. Duration and Period

Duration measures time on a machine clock — hours, minutes, seconds, nanos. Period measures time in human terms — years, months, days. Never use Duration for birthdays and never use Period for elapsed execution time.

Duration = machine clock (ঘণ্টা-মিনিট-সেকেন্ড)। Period = human calendar (বছর-মাস-দিন)। জন্মদিন-এ Period, code execution-এ Duration।
Main.java
import java.time.*;

class Main {
    public static void main(String[] args) throws Exception {
        Instant t0 = Instant.now();
        Thread.sleep(120);
        Instant t1 = Instant.now();
        Duration elapsed = Duration.between(t0, t1);
        System.out.println("elapsed ms = " + elapsed.toMillis());

        LocalDate bday  = LocalDate.of(2000, 1, 15);
        LocalDate today = LocalDate.of(2025, 4, 18);
        Period age = Period.between(bday, today);
        System.out.println("age = " + age.getYears() + "y " +
            age.getMonths() + "m " + age.getDays() + "d");
    }
}

6. Formatting and Parsing — DateTimeFormatter

Every type has toString() that produces an ISO-8601 string, but for UI or for non-standard input you use DateTimeFormatter. Many built-in formatters exist; you can also use a pattern string.

default-এ ISO-8601 string আসে। UI-তে অন্য format লাগলে DateTimeFormatter দিয়ে pattern দিন। কিছু standard formatter আগে থেকেই আছে।
Main.java
import java.time.*;
import java.time.format.*;

class Main {
    public static void main(String[] args) {
        LocalDate d = LocalDate.of(2025, 4, 18);

        DateTimeFormatter bd = DateTimeFormatter.ofPattern("dd MMM yyyy");
        System.out.println(bd.format(d));

        LocalDate parsed = LocalDate.parse("18/04/2025",
            DateTimeFormatter.ofPattern("dd/MM/yyyy"));
        System.out.println("parsed = " + parsed);
        System.out.println("iso    = " + parsed.format(DateTimeFormatter.ISO_DATE));
    }
}

7. Vocabulary

TermMeaningবাংলায়
EpochThe reference moment — 1970-01-01 00:00:00 UTC.Unix epoch — 1970 UTC।
ISO-8601The international date/time string standard (2025-04-18T14:30+06:00).আন্তর্জাতিক date/time standard।
ZoneIdA named timezone — Asia/Dhaka, Europe/London.নামযুক্ত timezone।
UTCUniversal coordinated time — the zero-offset reference.global reference সময়।
ImmutableEvery modification returns a new object.পরিবর্তন হলে নতুন object আসে।
DSTDaylight Saving Time — seasonal offset jumps.Daylight Saving — season-এ offset পাল্টায়।

8. Practice Problems

  1. Print today's date in the format Friday, 18 April 2025.
    আজকের তারিখ Friday, 18 April 2025 format-এ print করুন।
    Show Answer (উত্তর দেখুন)
    Main.java
    import java.time.*;
    import java.time.format.*;
    class Main {
        public static void main(String[] args) {
            LocalDate today = LocalDate.now();
            DateTimeFormatter f = DateTimeFormatter.ofPattern("EEEE, d MMMM yyyy");
            System.out.println(today.format(f));
        }
    }
  2. Given a birthday 2000-01-15, print the age in years, months, and days.
    জন্মদিন 2000-01-15 থেকে বছর-মাস-দিনে বয়স print করুন।
    Show Answer (উত্তর দেখুন)
    Main.java
    import java.time.*;
    class Main {
        public static void main(String[] args) {
            LocalDate b = LocalDate.of(2000, 1, 15);
            Period age = Period.between(b, LocalDate.now());
            System.out.printf("%d years, %d months, %d days%n",
                age.getYears(), age.getMonths(), age.getDays());
        }
    }
  3. Show the same Instant in Dhaka and New York timezones.
    একই Instant ঢাকা ও New York zone-এ দেখান।
    Show Answer (উত্তর দেখুন)
    Main.java
    import java.time.*;
    class Main {
        public static void main(String[] args) {
            Instant now = Instant.parse("2025-04-18T08:00:00Z");
            System.out.println("Dhaka    : " + now.atZone(ZoneId.of("Asia/Dhaka")));
            System.out.println("New York : " + now.atZone(ZoneId.of("America/New_York")));
        }
    }
  4. Explain in 2 sentences when to pick Duration vs Period.
    দুই বাক্যে বলুন — Duration ও Period কখন ব্যবহার করবেন।
    Show Answer (উত্তর দেখুন)

    Answer: Use Duration for machine time — elapsed execution, HTTP timeouts, sleep intervals — because it measures seconds and nanoseconds. Use Period for human calendar gaps — age, lease length, billing cycle — because it measures years, months, and days which are not fixed-length in seconds.

    machine সময়ে (execution, HTTP timeout, sleep) — Duration ব্যবহার করুন (সেকেন্ড-মিলিসেকেন্ড)। human calendar-এ (বয়স, lease, billing cycle) — Period ব্যবহার করুন (বছর-মাস-দিন, যা সেকেন্ডে ধ্রুব নয়)।

  5. Parse the string "2025-04-18 13:30" into a LocalDateTime and add 90 minutes.
    "2025-04-18 13:30"-কে LocalDateTime-এ parse করে ৯০ মিনিট যোগ করুন।
    Show Answer (উত্তর দেখুন)
    Main.java
    import java.time.*;
    import java.time.format.*;
    class Main {
        public static void main(String[] args) {
            DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
            LocalDateTime t = LocalDateTime.parse("2025-04-18 13:30", f);
            System.out.println("start  = " + t);
            System.out.println("plus90 = " + t.plusMinutes(90));
        }
    }

Summary — Module 34

java.time is the modern, immutable, thread-safe date/time API. Use LocalDate, LocalTime, LocalDateTime for zone-less values, ZonedDateTime when a timezone matters, and Instant for machine timestamps. Duration is for machine time, Period is for human calendar time, and DateTimeFormatter handles parsing and formatting. Never touch Date or Calendar again.

java.time — আধুনিক, immutable, thread-safe। zone-less হলে Local*, timezone দরকার হলে ZonedDateTime, machine timestamp-এ Instant। Duration machine-সময়ে, Period human-calendar-এ। DateTimeFormatter parse ও format করে।

Next Module → Strings Deep Dive — immutability, StringBuilder, text blocks।