openplanning

Hướng dẫn và ví dụ Java Temporal

  1. Temporal
  2. Temporal methods
  3. isSupported(TemporalUnit)
  4. with(TemporalAdjuster)
  5. with(TemporalField, long)
  6. plus(TemporalAmount)
  7. plus(long, TemporalUnit)
  8. minus(TemporalAmount)
  9. minus(long, TemporalUnit)
  10. until(Temporal, TemporalUnit)

1. Temporal

Interface Temporal mô phỏng một khái niệm chung nhất giữa các khái niệm ngày tháng (date), thời gian (time) và độ lệch thời gian (time-offset). Nó cung cấp các phương thức cơ bản để để lấy được các thông tin từ các đối tượng này.
public interface Temporal extends TemporalAccessor
Interface Temporal mở rộng từ interface TemporalAccessor, và chúng có một chút khác biệt:
TemporalAccessor
Mô phỏng một khái niệm chung nhất giữa các khái niệm ngày tháng (date), thời gian (time), độ lệch thời gian (time-offset), độ lệch múi giờ (zone-offset) và kỷ nguyên (era)
Temporal
Mô phỏng một khái niệm chung nhất giữa các khái niệm ngày tháng (date), thời gian (time) và độ lệch thời gian (time-offset).
Như vậy, Interface Temporal rút gọn số lượng các khái niệm mà nó đại diện so với TemporalAccessor. Nó cung cấp nhiều hơn các phương thức chi tiết hơn về các khái niệm này.
Danh sách các lớp con hoặc enum thực hiện (implement) interface Temporal:

2. Temporal methods

public boolean isSupported(TemporalUnit unit);

public default Temporal with(TemporalAdjuster adjuster)

public Temporal with(TemporalField field, long newValue);

public default Temporal plus(TemporalAmount amount)  

public Temporal plus(long amountToAdd, TemporalUnit unit);

public default Temporal minus(TemporalAmount amount)  

public default Temporal minus(long amountToSubtract, TemporalUnit unit)  

public long until(Temporal endExclusive, TemporalUnit unit);

3. isSupported(TemporalUnit)

Kiểm tra xem đơn vị tính (unit) chỉ định có được Temporal này hỗ trợ hay không.
public boolean isSupported(TemporalUnit unit)
Việc kiểm tra này là cần thiết trước khi sử dụng phương thức plus(long,TemporalUnit) hoặc minus(long,TemporalUnit). Nếu gọi các phương thức này với một đơn vị tính không được hỗ trợ ngoại lệ sẽ được ném ra.
Temporal_isSupported_x1.java
Temporal localDate = LocalDate.now();

boolean supported = localDate.isSupported(ChronoField.DAY_OF_MONTH);
System.out.println("localDate support DAY_OF_MONTH? " + supported); // true

Temporal localTime = LocalTime.now();

supported = localTime.isSupported(ChronoField.DAY_OF_MONTH);
System.out.println("localTime support DAY_OF_MONTH? " + supported); // false
Bạn cũng có thể sử dụng phương thức TemporalUnit.isSupportedBy(Temporal) để kiểm tra xem một TemporalUnit cụ thể có được hỗ trợ bởi một Temporal nào đó hay không.
TemporalUnit_isSupportedBy_x1.java
Temporal localDate = LocalDate.now();

boolean supported = ChronoField.DAY_OF_MONTH.isSupportedBy(localDate);
System.out.println("localDate support DAY_OF_MONTH? " + supported); // true

4. with(TemporalAdjuster)

Trả về bản sao của đối tượng Temporal này với một vài thông tin bị điều chỉnh bởi đối tượng TemporalAdjuster chỉ định.
public default Temporal with(TemporalAdjuster adjuster)
Về cơ bản có 2 cách để điều chỉnh một đối tượng Temporal, cách tiếp cận thứ 2 được khuyến khích sử dụng:
Temporal adjustedCopy = temporalAdjuster.adjustInto(temporal);  // (1)

Temporal adjustedCopy = temporal.with(temporalAdjuster);           // (2)
Ví dụ:
Temporal_with_adjuster_ex1.java
// Temporal object:
Temporal localDateTime = LocalDateTime.of(2020, 1, 1, 13, 30, 45);
System.out.println("localDateTime: " + localDateTime); // 2020-01-01T13:30:45

// TemporalAdjuter object:
TemporalAdjuster adjuster = Month.JULY;

LocalDateTime adjustedLocalDateTime = (LocalDateTime) localDateTime.with(adjuster);
System.out.println("adjustedLocalDateTime: " + adjustedLocalDateTime); // 2020-07-01T13:30:45
Xem thêm bài viết về TemporalAdjuster để có thêm nhiều ví dụ hơn:

5. with(TemporalField, long)

Trả về bản sao của đối tượng Temporal này với trường (field) chỉ định được thay đổi.
public Temporal with(TemporalField field, long newValue)
Trong một số trường hợp, việc thay đổi một trường có thể làm một trường khác trở thành không hợp lệ. Chẳng hạn ngày 31 tháng 1, việc đổi từ tháng 1 thành tháng 2 sẽ làm ngày trong tháng (day-of-month) trở thành không hợp lệ, phương thức này sẽ thay đổi ngày trong tháng thành một ngày hợp lệ gần nhất.
Temporal_with_field_ex1.java
// Temporal object:
Temporal localDate1 = LocalDate.of(2020, 1, 15);
System.out.println("localDate1: " + localDate1); // 2020-01-15

Temporal copiedLocalDate1 = localDate1.with(ChronoField.MONTH_OF_YEAR, 2);
System.out.println("copiedLocalDate1: " + copiedLocalDate1); // 2020-02-15
System.out.println();

// Temporal object:
Temporal localDate2 = LocalDate.of(2020, 1, 31);
System.out.println("localDate2: " + localDate2); // 2020-01-31

Temporal copiedLocalDate2 = localDate2.with(ChronoField.MONTH_OF_YEAR, 2);
System.out.println("copiedLocalDate2: " + copiedLocalDate2); // 2020-02-29
  • ChronoField
  • TemporalField

6. plus(TemporalAmount)

Trả về bản sao của Temporal này với một lượng thời gian chỉ định được thêm vào.
public default Temporal plus(TemporalAmount amount)
Ví dụ:
Temporal_plus_amount_ex1.java
Temporal localDateTime = LocalDateTime.of(2020,5,15, 13,30,45);
System.out.println("localDateTime: " + localDateTime); // 2020-05-15T13:30:45
System.out.println();
 
// plus(TemporalAmount amountToAdd)
TemporalAmount amount1 = Period.ofDays(5);
LocalDateTime localDateTime1 = (LocalDateTime) localDateTime.plus(amount1);
System.out.println("localDateTime1: " + localDateTime1); // 2020-05-20T13:30:45
 
// 1 day 2 hours 30 minutes.
TemporalAmount amount2 = Duration.ofMinutes(1* 24 * 60 + 2* 60 + 30);
LocalDateTime localDateTime2 = (LocalDateTime) localDateTime.plus(amount2);
System.out.println("localDateTime2: " + localDateTime2); // 2020-05-16T16:00:45
Phương thức Temporal.plus(TemporalAmount) làm việc tương tự như phương thức TemporalAmount.addTo(Temporal):
// This method is defined in the TemporalAmount interface:
public Temporal addTo(Temporal temporal)

7. plus(long, TemporalUnit)

Trả về một bản sao của Temporal này với một lượng giá trị được thêm vào theo đơn vị tính chỉ định.
public Temporal plus(long amountToAdd, TemporalUnit unit)
Ví dụ:
Temporal_plus_unit_ex1.java
Temporal localDateTime = LocalDateTime.of(2020, 5, 15, 13, 30, 45);
System.out.println("localDateTime: " + localDateTime); // 2020-05-15T13:30:45
System.out.println();

// plus(long amountToAdd, TemporalUnit unit)
LocalDateTime localDateTime1 = (LocalDateTime) localDateTime.plus(20, ChronoUnit.DAYS);
System.out.println("localDateTime1: " + localDateTime1); // 2020-06-04T13:30:45

// plus(long amountToAdd, TemporalUnit unit)
LocalDateTime localDateTime2 = (LocalDateTime) localDateTime.plus(2, ChronoUnit.WEEKS);
System.out.println("localDateTime2: " + localDateTime2); // 2020-05-29T13:30:45
Phương thức Temporal.plus(long,TemporalUnit) làm việc tương tự như phương thức TemporalUnit.addTo(R,long):
// This method is defined in the TemporalUnit interface:
public <R extends Temporal> R addTo(R temporal, long amount)

8. minus(TemporalAmount)

Trả về bản sao của Temporal này với một lượng thời gian được trừ đi.
public default Temporal minus(TemporalAmount amount)
Ví dụ:
Temporal_minus_amount_ex1.java
Temporal localDateTime = LocalDateTime.of(2020,5,15, 13,30,45);
System.out.println("localDateTime: " + localDateTime); // 2020-05-15T13:30:45
System.out.println();
 
// minus(TemporalAmount amountToAdd)
TemporalAmount amount1 = Period.ofDays(5);
LocalDateTime localDateTime1 = (LocalDateTime) localDateTime.minus(amount1);
System.out.println("localDateTime1: " + localDateTime1); // 2020-05-10T13:30:45
 
// 1 day 2 hours 30 minutes.
TemporalAmount amount2 = Duration.ofMinutes(1* 24 * 60 + 2* 60 + 30);
LocalDateTime localDateTime2 = (LocalDateTime) localDateTime.minus(amount2);
System.out.println("localDateTime2: " + localDateTime2); // 2020-05-14T11:00:45
Phương thức Temporal.minus(TemporalAmount) làm việc tương tự như phương thức TemporalAmount.subtractFrom(Temporal):
// This method is defined in the TemporalAmount interface:
public Temporal subtractFrom(Temporal temporal)

9. minus(long, TemporalUnit)

Trả về một bản sao của Temporal này với một lượng giá trị chỉ định được trừ đi theo đơn vị tính chỉ định.
public default Temporal minus(long amountToSubtract, TemporalUnit unit)
Ví dụ:
Temporal_minus_unit_ex1.java
Temporal localDateTime = LocalDateTime.of(2020, 5, 15, 13, 30, 45);
System.out.println("localDateTime: " + localDateTime); // 2020-05-15T13:30:45
System.out.println();

// minus(long amountToAdd, TemporalUnit unit)
LocalDateTime localDateTime1 = (LocalDateTime) localDateTime.minus(20, ChronoUnit.DAYS);
System.out.println("localDateTime1: " + localDateTime1); // 2020-04-25T13:30:45

// minus(long amountToAdd, TemporalUnit unit)
LocalDateTime localDateTime2 = (LocalDateTime) localDateTime.minus(20, ChronoUnit.HOURS);
System.out.println("localDateTime2: " + localDateTime2); // 2020-05-14T17:30:45

10. until(Temporal, TemporalUnit)

Tính lượng thời gian từ Temporal này cho tới một Temporal khác theo đơn vị tính được chỉ định.
(**) Đơn vị tính được chỉ định phải được hỗ trợ bởi cả 2 đối tượng Temporal tham gia trong phương thức, nếu không DateTimeException sẽ bị ném ra.
public long until(Temporal endExclusive, TemporalUnit unit)
Ví dụ:
Temporal_until_ex1.java
Temporal temporalFrom = LocalDateTime.of(2020, 5, 15, 13, 30, 45);
System.out.println("temporalFrom: " + temporalFrom); // 2020-05-15T13:30:45

Temporal temporalTo = LocalDate.of(2020, 5, 16).atStartOfDay(); // LocalDateTime
System.out.println("temporalTo: " + temporalTo); // 2020-05-16T00:00
System.out.println();

long hourAmount = temporalFrom.until(temporalTo, ChronoUnit.HOURS);
System.out.println("hourAmount: " + hourAmount); // 10
Bạn cũng có thể sử dụng phương thức TemporalUnit.between(Temporal,Temporal) trong trường hợp tương tự:
TemporalUnit_between_ex1.java
Temporal temporalFrom = LocalDateTime.of(2020, 5, 15, 13, 30, 45);
System.out.println("temporalFrom: " + temporalFrom); // 2020-05-15T13:30:45

Temporal temporalTo = LocalDate.of(2020, 5, 16).atStartOfDay(); // LocalDateTime
System.out.println("temporalTo: " + temporalTo); // 2020-05-16T00:00
System.out.println();

long hourAmount = ChronoUnit.HOURS.between(temporalFrom, temporalTo);
System.out.println("hourAmount: " + hourAmount); // 10