openplanning

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

  1. ChronoUnit
  2. ChronoUnit Values
  3. ChronoUnit methods
  4. CENTURIES
  5. DAYS
  6. DECADES
  7. ERAS
  8. FOREVER
  9. HALF_DAYS
  10. HOURS
  11. MICROS
  12. MILLENNIA
  13. MILLIS
  14. MINUTES
  15. MONTHS
  16. NANOS
  17. SECONDS
  18. WEEKS
  19. YEARS
  20. getDuration()
  21. isDurationEstimated()
  22. isDateBased()
  23. isTimeBased()
  24. isSupportedBy(Temporal)
  25. addTo(R temporal, long amount)
  26. between(Temporal, Temporal)

1. ChronoUnit

ChronoUnit là một enum thi hành interface TemporalUnit, nó cung cấp các đơn vị tính tiêu chuẩn được sử dụng trong Java Date Time API. Về cơ bản các đơn vị tính này là đủ để sử dụng, tuy nhiên nếu muốn có một đơn vị tính tuỳ biến hãy viết một lớp thi hành interface TemporalUnit.
public enum ChronoUnit implements TemporalUnit
  • TemporalField
  • TemporalUnit
  • ChronoField
Những đơn vị này được thiết kế để có thể áp dụng trong nhiều hệ thống lịch. Ví dụ, hầu hết các hệ thống lịch "không phải ISO" xác định các đơn vị năm, tháng và ngày, chỉ với các quy tắc hơi khác nhau. Tài liệu của mỗi đơn vị giải thích cách nó hoạt động.

2. ChronoUnit Values

Enum
Display Name
Estimated Duration
NANOS
Nanos
Duration.ofNanos(1)
MICROS
Micros
Duration.ofNanos(1000)
MILLIS
Millis
Duration.ofNanos(1000_000)
SECONDS
Seconds
Duration.ofSeconds(1)
MINUTES
Minutes
Duration.ofSeconds(60)
HOURS
Hours
Duration.ofSeconds(3600)
HALF_DAYS
HalfDays
Duration.ofSeconds(43200)
DAYS
Days
Duration.ofSeconds(86400)
WEEKS
Weeks
Duration.ofSeconds(7 * 86400L)
MONTHS
Months
Duration.ofSeconds(31556952L / 12)
YEARS
Years
Duration.ofSeconds(31556952L)
DECADES
Decades
Duration.ofSeconds(31556952L * 10L)
CENTURIES
Centuries
Duration.ofSeconds(31556952L * 100L)
MILLENNIA
Millennia
Duration.ofSeconds(31556952L * 1000L)
ERAS
Eras
Duration.ofSeconds(31556952L * 1000_000_000L)
FOREVER
Forever
Duration.ofSeconds(Long.MAX_VALUE, 999_999_999)

3. ChronoUnit methods

public Duration getDuration()   

public boolean isDurationEstimated()  

public boolean isDateBased()  

public boolean isTimeBased()  

public boolean isSupportedBy(Temporal temporal)  

public <R extends Temporal> R addTo(R temporal, long amount)  

public long between(Temporal temporal1Inclusive, Temporal temporal2Exclusive)

4. CENTURIES

Đơn vị tính đại diện cho khái niệm thế kỷ. Đối với hệ thống lịch ISO, nó bằng 100 năm.
Điều trên cũng đúng với các hệ thống lịch Hijrah, Japanese, MinguoThaiBuddhist.
Khi được sử dụng với các hệ thống lịch khác, nó phải tương ứng với số ngày nguyên và thường là số năm nguyên.

5. DAYS

Đơn vị đại diện cho khái niệm ngày. Đối với hệ thống lịch ISO, nó là ngày tiêu chuẩn từ nửa đêm đến nửa đêm. Thời lượng ước tính của một ngày là 24 giờ.
Điều trên cũng đúng với các hệ thống lịch Hijrah, Japanese, MinguoThaiBuddhist.
Khi được sử dụng với các hệ thống lịch khác, nó phải tương ứng với ngày được xác định bởi sự mọc và lặn của Mặt trời trên Trái đất. Không bắt buộc các ngày phải bắt đầu lúc nửa đêm - khi chuyển đổi giữa các hệ thống lịch, chúng nên bị giao nhau vào giữa trưa.
Ví dụ: Tìm số ngày giữa 2 thời điểm.
ChronoUnit_DAYS_ex1.java
LocalDateTime localDateTime1 = LocalDateTime.of(2020, 3, 15, 0, 30, 45);
LocalDateTime localDateTime2 = LocalDateTime.of(2020, 3, 17, 13, 30, 45);

Duration duration = Duration.between(localDateTime1, localDateTime2);
System.out.println("duration: " + duration); // PT61H (61 Hours)

long days = ChronoUnit.DAYS.between(localDateTime1, localDateTime2);
System.out.println("days: " + days); // 2
Ví dụ: Cộng thêm 2 ngày.
ChronoUnit_DAYS_ex2.java
ZonedDateTime now = ZonedDateTime.now();
// Plus 2 days
ZonedDateTime after2Days = now.plus(2, ChronoUnit.DAYS);

System.out.println("Now is: " + now);
System.out.println("After 2 days: " + after2Days);
Output:
Now is: 2021-07-17T00:50:13.048263+06:00[Asia/Bishkek]
After 2 days: 2021-07-19T00:50:13.048263+06:00[Asia/Bishkek]

6. DECADES

Đơn vị đại diện cho khái niệm của một thập kỷ. Đối với hệ thống lịch ISO, nó bằng 10 năm.
Điều trên cũng đúng với các hệ thống lịch Hijrah, Japanese, MinguoThaiBuddhist.
Khi được sử dụng với các hệ thống lịch khác, nó phải tương ứng với số nguyên ngày và thường là số nguyên của năm.

7. ERAS

Đơn vị đại diện cho khái niệm kỷ nguyên (Era).
Hệ thống lịch ISO không có khái niệm kỷ nguyên, vì vậy nó không xuất hiện trong chuỗi có định dạng ngày tháng và thời gian. Khoảng thời gian ước tính một cách giả tạo của kỷ nguyên trong hệ thống này là 1 tỷ năm.
Calendar system
Date Time String
ISO
1989-02-08
Japanese Imperial Calendar
Japanese Heisei 1-02-08
Kỷ nguyên gắn với khoảng thời gian trị vì của một vị vua hoặc khoảng thời gian tồn tại của một triều đại. Khái niệm kỷ nguyên thể hiện rõ ràng nhất trong hệ thống lịch hoàng gia Nhật Bản.
Khi được sử dụng với các hệ thống lịch khác, không có hạn chế nào về giá trị của nó.
ChronoUnit_ERAS_ex1.java
LocalDate isoDate = LocalDate.of(2020, 3, 15);
System.out.printf("isoDate: %s%n%n", isoDate); // 2020-03-15

JapaneseDate japaneseDate = JapaneseDate.from(isoDate);
JapaneseEra era = japaneseDate.getEra();

System.out.printf("japaneseDate: %s%n", japaneseDate); // Japanese Reiwa 2-03-15
System.out.printf(" > era: %s", era); // Reiwa
Output:
isoDate: 2020-03-15

japaneseDate: Japanese Reiwa 2-03-15
 > era: Reiwa

8. FOREVER

Đơn vị nhân tạo đại diện cho khái niệm mãi mãi. Điều này chủ yếu được sử dụng với TemporalField để đại diện cho các trường không bị ràng buộc như năm hoặc kỷ nguyên (era). Thời lượng ước tính của đơn vị này được xác định một cách giả tạo là thời lượng lớn nhất được Duration hỗ trợ.
Duration maxDuration = ChronoUnit.FOREVER.getDuration();
Ví dụ:
ChronoUnit_FOREVER_ex1.java
for (final ChronoUnit unit : ChronoUnit.values()) {
    final Duration duration = unit.getDuration();
    System.out.println(unit + ": " + duration + " (" + duration.getSeconds() + " seconds)");
}
Output:
Nanos: PT0.000000001S (0 seconds)
Micros: PT0.000001S (0 seconds)
Millis: PT0.001S (0 seconds)
Seconds: PT1S (1 seconds)
Minutes: PT1M (60 seconds)
Hours: PT1H (3600 seconds)
HalfDays: PT12H (43200 seconds)
Days: PT24H (86400 seconds)
Weeks: PT168H (604800 seconds)
Months: PT730H29M6S (2629746 seconds)
Years: PT8765H49M12S (31556952 seconds)
Decades: PT87658H12M (315569520 seconds)
Centuries: PT876582H (3155695200 seconds)
Millennia: PT8765820H (31556952000 seconds)
Eras: PT8765820000000H (31556952000000000 seconds)
Forever: PT2562047788015215H30M7.999999999S (9223372036854775807 seconds)

9. HALF_DAYS

Đơn vị đại diện cho khái niệm nửa ngày, như được sử dụng trong AM/PM. Đối với hệ thống lịch ISO, nó bằng 12 giờ.
Ví dụ: Cắt cụt (truncate) phần dư khi chia cho nửa ngày khỏi một LocalDateTime.
ChronoUnit_HALF_DAYS_ex1.java
LocalDateTime localDateTime1 = LocalDateTime.of(2020, 3, 15, 9, 30, 45);
LocalDateTime truncatedLDT1 = localDateTime1.truncatedTo(ChronoUnit.HALF_DAYS);

System.out.printf("localDateTime1: %s%n", localDateTime1); // 2020-03-15T09:30:45
System.out.printf(" > truncated: %s%n%n", truncatedLDT1);  // 2020-03-15T00:00

LocalDateTime localDateTime2 = LocalDateTime.of(2020, 3, 15, 13, 30, 45);
LocalDateTime truncatedLDT2 = localDateTime2.truncatedTo(ChronoUnit.HALF_DAYS);

System.out.printf("localDateTime2: %s%n", localDateTime2); // 2020-03-15T13:30:45
System.out.printf(" > truncated: %s", truncatedLDT2);      // 2020-03-15T12:00
Output:
localDateTime1: 2020-03-15T09:30:45
 > truncated: 2020-03-15T00:00

localDateTime2: 2020-03-15T13:30:45
 > truncated: 2020-03-15T12:00

10. HOURS

Đơn vị đại diện cho khái niệm giờ. Đối với hệ thống lịch ISO, nó bằng 60 phút.
Ví dụ:
ChronoUnit_HOURS_ex1.java
ZonedDateTime parisNow = ZonedDateTime.now(ZoneId.of("Europe/Paris"));
System.out.println("Now in Paris: " + parisNow);
  
ZonedDateTime parisNowHour = parisNow.truncatedTo(ChronoUnit.HOURS);
System.out.println("Truncated to Hour: " + parisNowHour);
Output:
Now in Paris: 2021-07-17T05:40:15.939515+02:00[Europe/Paris]
Truncated to Hour: 2021-07-17T05:00+02:00[Europe/Paris]

11. MICROS

Đơn vị đại diện cho khái niệm micro giây. Đối với hệ thống lịch ISO, 1 giây bằng 1 triệu micro giây.

12. MILLENNIA

Đơn vị đại diện cho khái niệm thiên niên kỷ. Đối với hệ thống lịch ISO, nó bằng 1000 năm.
Điều trên cũng đúng với các hệ thống lịch Hijrah, Japanese, MinguoThaiBuddhist.
Khi được sử dụng với các hệ thống lịch khác, nó phải tương ứng với số nguyên ngày và thường là số nguyên của năm.

13. MILLIS

Đơn vị đại diện cho khái niệm mili giây. Đối với hệ thống lịch ISO, 1 giây bằng 1000 mili giây.

14. MINUTES

Đơn vị thể hiện khái niệm phút. Đối với hệ thống lịch ISO, nó bằng 60 giây.

15. MONTHS

Đơn vị đại diện cho khái niệm tháng. Đối với hệ thống lịch ISO, độ dài của tháng thay đổi theo tháng trong năm. Thời lượng ước tính của một tháng là một phần mười hai của 365,2425 ngày.
Khi được sử dụng với các hệ thống lịch khác, nó phải tương ứng với một số nguyên ngày.

16. NANOS

Đơn vị đại diện cho khái niệm nano giây, đơn vị thời gian nhỏ nhất được hỗ trợ. Đối với hệ thống lịch ISO, 1 giây bằng 1 tỷ nano giây.

17. SECONDS

Đơn vị đại diện cho khái niệm giây. Đối với hệ thống lịch ISO, nó bằng giây trong hệ đơn vị SI, ngoại trừ khoảng một giây nhuận.

18. WEEKS

Đơn vị đại diện cho khái niệm một tuần. Đối với hệ thống lịch ISO, nó bằng 7 ngày.
Điều trên cũng đúng với các hệ thống lịch Hijrah, Japanese, MinguoThaiBuddhist.
Khi được sử dụng với các hệ thống lịch khác, nó phải tương ứng với một số nguyên ngày.

19. YEARS

Đơn vị đại diện cho khái niệm của một năm. Đối với hệ thống lịch ISO, nó bằng 12 tháng. Thời hạn ước tính của một năm là 365,2425 Ngày.
Một năm trong các hệ thống lịch Hijrah, Japanese, MinguoThaiBuddhist cũng bằng 12 tháng.
Khi được sử dụng với các hệ thống lịch khác, nó phải tương ứng với một số nguyên ngày hoặc tháng gần bằng một năm được xác định bởi sự đi qua của Trái đất quanh Mặt trời.

20. getDuration()

Trả về thời lượng ước tính của đơn vị tính này trong hệ thống lịch ISO.
public Duration getDuration()
Tất cả các đơn vị trong lớp này đều có thời lượng ước tính. Các ngày thay đổi do "thời gian tiết kiệm ánh sáng ban ngày" (Daylight Saving Time - DST), trong khi các tháng có độ dài khác nhau.
Ví dụ: Một tháng được ước tính là 30 theo đơn vị ngày, nhưng trong đơn vị giờ nó được ước tính là 730 (tương đương 30.41 ngày).
ChronoUnit_getDuration_ex1.java
Duration monthDuration = ChronoUnit.MONTHS.getDuration();  
// to days: 30 days
System.out.println("monthDuration.toDays(): " + monthDuration.toDays());  

// to hours: 730 hours ~ 30.41 days.
System.out.println("monthDuration.toHours(): " + monthDuration.toHours());
Output:
monthDuration.toDays(): 30
monthDuration.toHours(): 730
Ví dụ: Ước lượng số giờ trong "1 năm 2 tháng 15 ngày".
ChronoUnit_getDuration_ex2.java
Period period = Period.of(1, 2, 15); // 1 year 2 months 15 days.

int years = period.getYears(); // 1
int months = period.getMonths(); // 2
int days = period.getDays(); // 15

System.out.println("years: " + years); // 1
System.out.println("months: " + months);// 2
System.out.println("days: " + days); // 15

Duration yearsDuration = ChronoUnit.YEARS.getDuration().multipliedBy(years);
Duration monthsDuration = ChronoUnit.MONTHS.getDuration().multipliedBy(months);
Duration daysDuration = ChronoUnit.DAYS.getDuration().multipliedBy(days);

Duration totalDuration = yearsDuration.plus(monthsDuration).plus(daysDuration);

long estimatedDays = totalDuration.toDays();
long estimatedHours = totalDuration.toHours();
System.out.println("Estimated days: " + estimatedDays); // 441 days
System.out.println("Estimated hours: " + estimatedHours); // 10586 hours ~ 441.08 days.
Output:
years: 1
months: 2
days: 15
Estimated days: 441
Estimated hours: 10586

21. isDurationEstimated()

Kiểm tra xem thời lượng của đơn vị có phải là ước tính hay không.
public boolean isDurationEstimated()
Tất cả các đơn vị thời gian trong lớp này được coi là chính xác, trong khi tất cả các đơn vị ngày trong lớp này được coi là ước tính. Xem thêm phương thức isTimeBased()isDateBased().
Định nghĩa này bỏ qua giây nhuận, nhưng cho rằng Ngày thay đổi do thời gian tiết kiệm ánh sáng ban ngày và các tháng có độ dài khác nhau.
Ví dụ: In ra danh sách các đơn vị tính chính xác của lớp này.
ChronoUnit_isDurationEstimated_ex1.java
for (ChronoUnit unit : ChronoUnit.values()) {
    if (unit.isDurationEstimated()) {
        System.out.println(unit.name());
    }
}
Output:
DAYS
WEEKS
MONTHS
YEARS
DECADES
CENTURIES
MILLENNIA
ERAS
FOREVER

22. isDateBased()

Kiểm tra xem đơn vị này có phải dựa trên ngày tháng không?
public boolean isDateBased()
Tất cả các đơn vị tính từ DAYS đến ERAS trả về true. Các đơn vị tính dựa trên thời gian và FOREVER trả về false.
ChronoUnit_isDateBased_ex1.java
for (ChronoUnit unit : ChronoUnit.values()) {
    if (unit.isDateBased()) {
        System.out.println(unit.name());
    }
}
Output:
DAYS
WEEKS
MONTHS
YEARS
DECADES
CENTURIES
MILLENNIA
ERAS

23. isTimeBased()

Kiểm tra xem đơn vị này có phải dựa trên thời gian không?
public boolean isTimeBased()
Tất cả các đơn vị tính từ NANOS đến HALF_DAYS trả về true. Các đơn vị tính dựa trên ngày tháng và FOREVER trả về false.
ChronoUnit_isTimeBased_ex1.java
for (ChronoUnit unit : ChronoUnit.values()) {
    if (unit.isTimeBased()) {
        System.out.println(unit.name());
    }
}
Output:
NANOS
MICROS
MILLIS
SECONDS
MINUTES
HOURS
HALF_DAYS

24. isSupportedBy(Temporal)

Kiểm tra xem đơn vị này có được hỗ trợ bởi đối tượng Temporal được chỉ định hay không.
public boolean isSupportedBy(Temporal temporal)
Ví dụ: Tìm các đơn vị tính được hỗ trợ bởi LocalDate:
ChronoUnit_isSupportedBy_ex1.java
Temporal localDate = LocalDate.now();
System.out.println("Does LocalDate support: ");

for(ChronoUnit unit: ChronoUnit.values()) {
    System.out.println(unit.name() + "? " + unit.isSupportedBy(localDate));  
}
Output:
Does LocalDate support:
NANOS? false
MICROS? false
MILLIS? false
SECONDS? false
MINUTES? false
HOURS? false
HALF_DAYS? false
DAYS? true
WEEKS? true
MONTHS? true
YEARS? true
DECADES? true
CENTURIES? true
MILLENNIA? true
ERAS? true
FOREVER? false

25. addTo(R temporal, long amount)

Trả về bản sao của đối tượng Temporal đã chỉ định với khoảng thời gian được chỉ định được thêm vào.
public <R extends Temporal> R addTo(R temporal, long amount)
Phương thức này tương đương với phương thức Temporal.plus(long,TemporalUnit), cách tiếp cận này được khuyến nghị sử dụng.
// Defined in Temporal interface
public Temporal plus​(long amountToAdd, TemporalUnit unit)
Ví dụ:
ChronoUnit_addTo_ex1.java
Temporal ym = YearMonth.of(2020, 3); // 2020-03
// Add 10 monthds to ym.
YearMonth ym2 = (YearMonth) ChronoUnit.MONTHS.addTo(ym, 10);

System.out.println("ym2: " + ym2); // 2021-01

26. between(Temporal, Temporal)

Trả về lượng thời gian giữa hai đối tượng Temporal. Đơn vị tính này cần được hỗ trợ bởi cả 2 đối tượng Temporal, nếu không ngoại lệ sẽ bị ném ra.
public long between(Temporal temporal1Inclusive, Temporal temporal2Exclusive)
Phương thức này tương đương với việc sử dụng phương thức Temporal.until(Temporal,TemporalUnit),
// Defined in Temporal interface
public long until​(Temporal endExclusive, TemporalUnit unit)
Ví dụ:
ChronoUnit_between_ex1.java
LocalDate from = LocalDate.of(2020, 3, 15);
LocalDate to = LocalDate.of(2020, 3, 17);

long days = ChronoUnit.DAYS.between(from, to);
System.out.println("days: " + days); // 2
Ví dụ:
ChronoUnit_between_ex2.java
YearMonth from = YearMonth.of(2020, 7);
LocalDateTime to = LocalDateTime.of(2021, 3, 17, 13, 45, 30);

long months = ChronoUnit.MONTHS.between(from, to);
System.out.println("months: " + months); // 8