Chuyển tới nội dung chính

API Date-Time trong Java

Java 8 giới thiệu một API Date-Time mới (java.time) để thay thế các lớp cũ như java.util.Date và java.util.Calendar. API mới này cung cấp một cách tiếp cận tốt hơn để làm việc với ngày tháng và thời gian.

1. Các Lớp Cơ Bản

LocalDate

// Lấy ngày hiện tại
LocalDate today = LocalDate.now();

// Tạo ngày cụ thể
LocalDate date = LocalDate.of(2024, 3, 15);

// Lấy các thành phần
int year = date.getYear();
int month = date.getMonthValue();
int day = date.getDayOfMonth();
DayOfWeek dayOfWeek = date.getDayOfWeek();

// Thêm/trừ ngày
LocalDate tomorrow = date.plusDays(1);
LocalDate lastMonth = date.minusMonths(1);

LocalTime

// Lấy thời gian hiện tại
LocalTime now = LocalTime.now();

// Tạo thời gian cụ thể
LocalTime time = LocalTime.of(14, 30, 0);

// Lấy các thành phần
int hour = time.getHour();
int minute = time.getMinute();
int second = time.getSecond();

// Thêm/trừ thời gian
LocalTime later = time.plusHours(2);
LocalTime earlier = time.minusMinutes(30);

LocalDateTime

// Lấy ngày giờ hiện tại
LocalDateTime now = LocalDateTime.now();

// Tạo ngày giờ cụ thể
LocalDateTime dateTime = LocalDateTime.of(2024, 3, 15, 14, 30);

// Chuyển đổi từ LocalDate và LocalTime
LocalDateTime dt = LocalDate.now().atTime(LocalTime.now());

// Thêm/trừ thời gian
LocalDateTime later = dateTime.plusDays(1).plusHours(2);

2. Xử Lý Thời Gian

Duration

// Tính khoảng thời gian giữa hai thời điểm
LocalTime start = LocalTime.of(9, 0);
LocalTime end = LocalTime.of(17, 0);
Duration duration = Duration.between(start, end);

// Lấy thông tin
long hours = duration.toHours();
long minutes = duration.toMinutes();
long seconds = duration.getSeconds();

// Tạo duration
Duration twoHours = Duration.ofHours(2);
Duration thirtyMinutes = Duration.ofMinutes(30);

Period

// Tính khoảng thời gian giữa hai ngày
LocalDate start = LocalDate.of(2024, 1, 1);
LocalDate end = LocalDate.of(2024, 12, 31);
Period period = Period.between(start, end);

// Lấy thông tin
int years = period.getYears();
int months = period.getMonths();
int days = period.getDays();

// Tạo period
Period oneYear = Period.ofYears(1);
Period sixMonths = Period.ofMonths(6);

3. Định Dạng và Phân Tích

DateTimeFormatter

// Định dạng ngày tháng
LocalDate date = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
String formatted = date.format(formatter);

// Phân tích chuỗi thành ngày tháng
String dateStr = "15/03/2024";
LocalDate parsed = LocalDate.parse(dateStr, formatter);

// Các định dạng phổ biến
DateTimeFormatter isoDate = DateTimeFormatter.ISO_LOCAL_DATE;
DateTimeFormatter isoTime = DateTimeFormatter.ISO_LOCAL_TIME;
DateTimeFormatter isoDateTime = DateTimeFormatter.ISO_LOCAL_DATE_TIME;

4. Xử Lý Múi Giờ

ZonedDateTime

// Lấy thời gian hiện tại với múi giờ
ZonedDateTime now = ZonedDateTime.now();

// Tạo thời gian với múi giờ cụ thể
ZoneId zone = ZoneId.of("Asia/Ho_Chi_Minh");
ZonedDateTime vietnamTime = ZonedDateTime.now(zone);

// Chuyển đổi múi giờ
ZonedDateTime tokyoTime = vietnamTime.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));

OffsetDateTime

// Lấy thời gian với offset
OffsetDateTime now = OffsetDateTime.now();

// Tạo thời gian với offset cụ thể
ZoneOffset offset = ZoneOffset.ofHours(7);
OffsetDateTime vietnamTime = OffsetDateTime.now(offset);

5. Ví Dụ Thực Tế

Xử Lý Đơn Hàng

public class Order {
private String orderId;
private LocalDateTime orderDate;
private LocalDateTime deliveryDate;

public Order(String orderId) {
this.orderId = orderId;
this.orderDate = LocalDateTime.now();
this.deliveryDate = orderDate.plusDays(3); // Giao hàng sau 3 ngày
}

public boolean isDelivered() {
return LocalDateTime.now().isAfter(deliveryDate);
}

public long getRemainingDays() {
return ChronoUnit.DAYS.between(LocalDateTime.now(), deliveryDate);
}
}

Quản Lý Lịch Hẹn

public class Appointment {
private String patientName;
private LocalDateTime appointmentTime;
private Duration duration;

public Appointment(String patientName, LocalDateTime time, Duration duration) {
this.patientName = patientName;
this.appointmentTime = time;
this.duration = duration;
}

public boolean isOverlapping(Appointment other) {
LocalDateTime thisEnd = appointmentTime.plus(duration);
LocalDateTime otherEnd = other.appointmentTime.plus(other.duration);

return appointmentTime.isBefore(otherEnd) &&
other.appointmentTime.isBefore(thisEnd);
}

public boolean isUpcoming() {
return appointmentTime.isAfter(LocalDateTime.now());
}
}

6. Best Practices

  1. Sử Dụng API Mới Thay Vì API Cũ

    // Không nên
    Date date = new Date();
    Calendar calendar = Calendar.getInstance();

    // Nên
    LocalDate date = LocalDate.now();
    LocalDateTime dateTime = LocalDateTime.now();
  2. Xử Lý Múi Giờ Đúng Cách

    // Không nên
    LocalDateTime dateTime = LocalDateTime.now();

    // Nên
    ZonedDateTime dateTime = ZonedDateTime.now(ZoneId.of("Asia/Ho_Chi_Minh"));
  3. Sử Dụng Immutable Objects

    // Không nên
    dateTime.setYear(2025);

    // Nên
    LocalDateTime newDateTime = dateTime.withYear(2025);

7. Lỗi Thường Gặp

  1. Quên Xử Lý Múi Giờ

    // Lỗi
    LocalDateTime dateTime = LocalDateTime.now();
    // Có thể gây ra vấn đề khi chuyển đổi múi giờ

    // Đúng
    ZonedDateTime dateTime = ZonedDateTime.now(ZoneId.of("Asia/Ho_Chi_Minh"));
  2. So Sánh Thời Gian Sai Cách

    // Lỗi
    if (date1 == date2) { }

    // Đúng
    if (date1.equals(date2)) { }
    if (date1.isBefore(date2)) { }
    if (date1.isAfter(date2)) { }
  3. Quên Xử Lý Ngoại Lệ

    // Lỗi
    LocalDate date = LocalDate.parse("invalid-date");

    // Đúng
    try {
    LocalDate date = LocalDate.parse("invalid-date");
    } catch (DateTimeParseException e) {
    // Xử lý ngoại lệ
    }