openplanning

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

  1. Period
  2. Static Factory Methods
  3. Other methods
  4. get(TemporalUnit)
  5. getX() *
  6. getUnits()
  7. getChronology()
  8. withX(..) *
  9. plus(TemporalAmount)
  10. plusX(..) *
  11. minus(TemporalAmount)
  12. minusX(..) *
  13. isZero()
  14. isNegative()
  15. multipliedBy(int)
  16. negated()
  17. normalized()
  18. toTotalMonths()
  19. addTo(Temporal)
  20. subtractFrom(Temporal)

1. Period

Lớp Period sử dụng các đơn vị tính năm, tháng và ngày để biểu thị một khoảng thời gian. Chẳng hạn "3 năm 2 tháng 15 ngày". Nếu bạn muốn một lượng thời gian dựa trên giờ phút và giây hãy sử dụng lớp Duration.
Các giá trị năm, tháng và ngày trong Period là độc lập với nhau, điều đó có nghĩa là nếu bạn thêm hoặc trừ một số ngày ra khỏi Period nó sẽ không ảnh hưởng tới năm và tháng, lý do cho điều này là độ dài của tháng và năm là không cố định.
public final class Period implements ChronoPeriod, Serializable
Ví dụ: Cầu thủ bóng đá Cristiano Ronaldo sinh ngày 05 tháng hai năm 1985. Ngày 29 tháng 9 năm 2002, Ronaldo có trận ra mắt đầu tiên tại Primeira Liga, như vậy lúc đó anh ta 17 tuổi, 7 tháng 24 ngày.
Period_ronaldo_ex1.java
// 1985-02-05 (Ronaldo's birthday).
LocalDate startInclusiveDate = LocalDate.of(1985, 2, 5);

// 2002-09-29 (First time playing in Primeira Liga ).
LocalDate endExclusiveDate = LocalDate.of(2002, 9, 29);

Period period = Period.between(startInclusiveDate, endExclusiveDate);

System.out.println(period); // P17Y7M24D
System.out.println("Years: " + period.getYears());  // 17
System.out.println("Months: " + period.getMonths()); // 7
System.out.println("Days: " + period.getDays()); // 24

2. Static Factory Methods

Các phương thức nhà máy tĩnh:
public static final Period ZERO = new Period(0, 0, 0);

public static Period ofYears(int years)  
public static Period ofMonths(int months)
public static Period ofWeeks(int weeks)
public static Period ofDays(int days)  
public static Period of(int years, int months, int days)
public static Period from(TemporalAmount amount)
public static Period parse(CharSequence text)  
public static Period between(LocalDate startDateInclusive, LocalDate endDateExclusive)

3. Other methods

Các phương thức khác:
// -----------------------------------------------------------------
// getX()
// -----------------------------------------------------------------

// Inherited from ChronoPeriod interface
public long get(TemporalUnit unit)

// Inherited from ChronoPeriod interface
public List<TemporalUnit> getUnits()  

// Inherited from ChronoPeriod interface
public IsoChronology getChronology()

public int getYears()  
public int getMonths()  
public int getDays()  

// -----------------------------------------------------------------
// withX()
// -----------------------------------------------------------------

public Period withYears(int years)
public Period withMonths(int months)  
public Period withDays(int days)  

// -----------------------------------------------------------------
// plusX()
// -----------------------------------------------------------------

// Inherited from ChronoPeriod interface
public Period plus(TemporalAmount amountToAdd)

public Period plusYears(long yearsToAdd)  
public Period plusMonths(long monthsToAdd)
public Period plusDays(long daysToAdd)

// -----------------------------------------------------------------
// minusX()
// -----------------------------------------------------------------

// Inherited from ChronoPeriod interface
public Period minus(TemporalAmount amountToSubtract)  

public Period minusYears(long yearsToSubtract)  
public Period minusMonths(long monthsToSubtract)
public Period minusDays(long daysToSubtract)  

// -----------------------------------------------------------------

public long toTotalMonths()  

// -----------------------------------------------------------------
//  Other method inherited from ChronoPeriod interface
// -----------------------------------------------------------------
 
public boolean isZero()   
public boolean isNegative()   
public Period multipliedBy(int scalar)  
public Period negated()   
public Period normalized()  
public Temporal addTo(Temporal temporal)
public Temporal subtractFrom(Temporal temporal)

4. get(TemporalUnit)

Trả về giá trị của đơn vị tính chỉ định.
// Inherited from ChronoPeriod interface
public long get(TemporalUnit unit) {
Chỉ 3 đơn vị tính tiêu chuẩn dưới đây được hỗ trợ, các đơn vị tính khác sẽ ném ra UnsupportedTemporalTypeException.
  • ChronoUnit.YEARS
  • ChronoUnit.MONTHS
  • ChronoUnit.DAYS
Ví dụ:
Period_get_unit_ex1.java
// 20 years 5 months 115 days.
Period period = Period.of(20, 5, 115);

long years = period.get(ChronoUnit.YEARS); // 20
long months = period.get(ChronoUnit.MONTHS); // 5
long days = period.get(ChronoUnit.DAYS); // 115

System.out.printf("%d years, %d months %d days", years, months, days);

5. getX() *

Phương thức getDays() trả về số ngày được biểu thị trong Period này. Các giá trị ngày, tháng, năm trong Period là độc lập với nhau, chúng không thể chuyển đổi với nhau vì độ dài tháng và năm là không cố định.
Các phương thức getMonths(), getYears() cũng được hiểu tương tự như cái tên của chúng.
public int getYears()  
public int getMonths()  
public int getDays()
Ví dụ: Ngày 20 tháng 7 năm 1969 tàu vũ trụ Apollo 11 đã đáp xuống mặt trăng, chúng ta có thể tính toán xem sự kiện này đã diễn ra bao lâu so với hiện tại:
Period_getX_ex1.java
// 1969-07-20
LocalDate apollo11Date = LocalDate.of(1969, 7, 20);

// Now
LocalDate now = LocalDate.now();
System.out.println("Now is " + now);

Period period = Period.between(apollo11Date, now);

System.out.println(period);  
System.out.println("Years: " + period.getYears());   
System.out.println("Months: " + period.getMonths());  
System.out.println("Days: " + period.getDays());
Output:
Now is 2021-06-25
P51Y11M5D
Years: 51
Months: 11
Days: 5
Thực tế để tính toán số năm, số tháng, số tuần hoặc số ngày giữa 2 thời điểm khác nhau bạn cũng có thể sử dụng lớp ChronoUnit, hãy xem ví dụ:
ChronoUnit_between_ex1.java
// 1969-07-20
LocalDate apollo11Date = LocalDate.of(1969, 7, 20);

// Now
LocalDate now = LocalDate.now();
System.out.println("Now is " + now);

long years = ChronoUnit.YEARS.between(apollo11Date, now);
long months = ChronoUnit.MONTHS.between(apollo11Date, now);
long weeks = ChronoUnit.WEEKS.between(apollo11Date, now);
long days = ChronoUnit.DAYS.between(apollo11Date, now);

System.out.println("Years: " + years);
System.out.println("Months: " + months);
System.out.println("Weeks: " + weeks);
System.out.println("Days:" + days);
Output:
Now is 2021-06-25
Years: 51
Months: 623
Weeks: 2709
Days:18968

6. getUnits()

Trả về các TemporalUnit được hỗ trợ bởi Period này, chỉ có 3 TemporalUnit tiêu chuẩn sau được hỗ trợ:
  • ChronoUnit.YEARS
  • ChronoUnit.MONTHS
  • ChronoUnit.DAYS
// Inherited from ChronoPeriod interface
public List<TemporalUnit> getUnits()
Ví dụ:
Period_getUnits_ex1.java
Period period = Period.of(2, 8, 0);  
// ChronoUnit.YEARS, ChronoUnit.MONTHS, ChronoUnit.DAYS
List<TemporalUnit> units = period.getUnits();

for(TemporalUnit unit: units)  {
    System.out.println("Unit: " + unit.getClass().getName() + " - " + unit);
}
Output:
Unit: java.time.temporal.ChronoUnit - Years
Unit: java.time.temporal.ChronoUnit - Months
Unit: java.time.temporal.ChronoUnit - Days

7. getChronology()

Trả về niên đại (chronology) của Period này, đó là hệ thống lịch ISO (IsoChronology.INSTANCE).
// Inherited from ChronoPeriod interface
public IsoChronology getChronology()
Ví dụ:
Period_getChronology_ex1.java
Period period = Period.of(20,  5,  10);
IsoChronology isoChronology    = period.getChronology();
System.out.println("IsoChronology: " + isoChronology.getId()); // ISO.
  • Hướng dẫn và ví dụ Java IsoChronology

8. withX(..) *

Phương thức withDays(days) trả về một bản sao của Period này với số ngày được thay thế bởi số ngày được chỉ định, năm và tháng không bị ảnh hưởng bởi phương thức này.
Các phương thức withYears(years), withMonths(months) cũng được hiểu tương tự như cái tên của chúng.
public Period withYears(int years)
public Period withMonths(int months)
public Period withDays(int days)
Ví dụ:
Period_withX_ex1.java
Period period = Period.of(20, 3, 15);
period = period.withDays(100);

System.out.println(period);
System.out.println("Years: " + period.getYears()); // 20
System.out.println("Months: " + period.getMonths()); // 3
System.out.println("Days: " + period.getDays()); // 100

9. plus(TemporalAmount)

Trả về bản sao của Period này với một lượng thời gian được thêm vào.
public Period plus(TemporalAmount amountToAdd)
Các giá trị được thêm vào ngày, tháng, năm là độc lập với nhau, sẽ không có quá trình chuẩn hoá nào được thực hiện. Chẳng hạn:
  • "2 years 10 months 110 days" + "3 years 5 months 10 days" --> "5 years 15 months 120 days".
Ví dụ:
Period_plus_amount_ex1.java
// 20 years 3 months 15 days.
Period period = Period.of(20, 3, 15);  
System.out.println("period: " + period); // P20Y3M15D

TemporalAmount amount = Period.ofMonths(15); // 15 months

Period period2 = period.plus(amount);
System.out.println("period2: " + period2); // P20Y18M15D (20 years, 18 months, 15 days)

10. plusX(..) *

Phương thức plusDays(daysToAdd) trả về một bản sao của Period này với số ngày chỉ định được thêm vào, việc này không ảnh hưởng tới giá trị của năm và tháng.
Các phương thức plusYears(yearsToAdd)plusMonths(monthsToAdd) cũng được hiểu tương tự như tên của chúng.
public Period plusYears(long yearsToAdd)  
public Period plusMonths(long monthsToAdd)
public Period plusDays(long daysToAdd)
Ví dụ:
Period_plusX_ex1.java
Period period = Period.of(20, 3, 15);  

// period1
Period period1 = period.plusDays(100);  

System.out.println("period1.getYears(): " + period1.getYears()); // 20
System.out.println("period1.getMonths(): " + period1.getMonths()); // 3
System.out.println("period1.getDays(): " + period1.getDays()); // 115
System.out.println(" ------- \n");

// period2
Period period2 = period.plusDays(-100);  

System.out.println("period2.getYears(): " + period2.getYears()); // 20
System.out.println("period2.getMonths(): " + period2.getMonths()); // 3
System.out.println("period2.getDays(): " + period2.getDays()); // -85
System.out.println(" ------- \n");

// period3
Period period3 = period.plusYears(-30);  

System.out.println("period3.getYears(): " + period3.getYears()); // -10
System.out.println("period3.getMonths(): " + period3.getMonths()); // 3
System.out.println("period3.getDays(): " + period3.getDays()); // 15
Output:
period1.getYears(): 20
period1.getMonths(): 3
period1.getDays(): 115
 -------

period2.getYears(): 20
period2.getMonths(): 3
period2.getDays(): -85
 -------

period3.getYears(): -10
period3.getMonths(): 3
period3.getDays(): 15

11. minus(TemporalAmount)

Trả về bản sao của Period này với một lượng thời gian chỉ định được trừ đi.
public Period minus(TemporalAmount amountToSubtract)
Các giá trị ngày, tháng, năm là độc lập với nhau, sẽ không có quá trình chuẩn hoá nào được thực hiện. Chẳng hạn:
  • "2 years 10 months 110 days" - "3 years 5 months 10 days" --> "-1 years 10 months 90 days".
Ví dụ:
Period_minus_amount_ex1.java
// 20 years 3 months 15 days.
Period period = Period.of(20, 3, 15);  
System.out.println("period: " + period); // P20Y3M15D

TemporalAmount amount = Period.ofMonths(5); // 5 months

Period period2 = period.minus(amount);
System.out.println("period2: " + period2); // P20Y-2M15D (20 years, -2 months, 15 days)
  • Hướng dẫn và ví dụ Java TemporalAmount

12. minusX(..) *

Phương thức minusDays(daysToSubtract) trả về một bản sao của Period này với số ngày chỉ định được trừ đi, việc này không ảnh hưởng tới 2 trường còn lại là năm và tháng.
Các phương thức minusYears(yearsToSubtract)minusMonths(monthsToSubtract) cũng được hiểu một cách tương tự như cái tên của chúng.
public Period minusYears(long yearsToSubtract)  
public Period minusMonths(long monthsToSubtract)  
public Period minusDays(long daysToSubtract)
Ví dụ:
Period_minusX_ex1.java
Period period = Period.of(20, 3, 15);  

// period1
Period period1 = period.minusDays(100);  

System.out.println("period1.getYears(): " + period1.getYears()); // 20
System.out.println("period1.getMonths(): " + period1.getMonths()); // 3
System.out.println("period1.getDays(): " + period1.getDays()); // -85
System.out.println(" ------- \n");

// period2
Period period2 = period.minusDays(-100);  

System.out.println("period2.getYears(): " + period2.getYears()); // 20
System.out.println("period2.getMonths(): " + period2.getMonths()); // 3
System.out.println("period2.getDays(): " + period2.getDays()); // 115
System.out.println(" ------- \n");

// period3
Period period3 = period.minusYears(30);  

System.out.println("period3.getYears(): " + period3.getYears()); // -10
System.out.println("period3.getMonths(): " + period3.getMonths()); // 3
System.out.println("period3.getDays(): " + period3.getDays()); // 15
Output:
period1.getYears(): 20
period1.getMonths(): 3
period1.getDays(): -85
 -------

period2.getYears(): 20
period2.getMonths(): 3
period2.getDays(): 115
 -------

period3.getYears(): -10
period3.getMonths(): 3
period3.getDays(): 15

13. isZero()

Trả về true nếu cả 3 giá trị ngày, tháng, năm trong Period này là 0, ngược lại trả về false.
// Inherited from ChronoPeriod interface
public boolean isZero()
Ví dụ:
Period_isZero_ex1.java
Period period1 = Period.of(0, -1, 30);
System.out.println("period1.isZero()? " + period1.isZero()); // false

Period period2 = Period.of(-1, 12, 0);
System.out.println("period2.isZero()? " + period2.isZero()); // false

Period period3 = Period.of(0, 0, 0);
System.out.println("period3.isZero()? " + period3.isZero()); // true

14. isNegative()

Trả về true nếu có bất kỳ ngày, tháng hoặc năm của Period này là số âm, ngược lại trả về false.
// Inherited from ChronoPeriod interface
public boolean isNegative()
Ví dụ:
Period_isNegative_ex1.java
Period period1 = Period.of(10, -1, 30);
System.out.println("period1.isNegative()? " + period1.isNegative()); // true

Period period2 = Period.of(1, -12, -15);
System.out.println("period2.isNegative()? " + period2.isNegative()); // true

Period period3 = Period.of(0, 0, 0);
System.out.println("period3.isNegative()? " + period3.isNegative()); // false  

Period period4 = Period.of(5, 10, 15);
System.out.println("period4.isNegative()? " + period4.isNegative()); // false

15. multipliedBy(int)

Nhân Period này với một giá trị được chỉ định và trả về một Period mới.
// Inherited from ChronoPeriod interface
public Period multipliedBy(int scalar)
Các giá trị ngày, tháng, năm là độc lập với nhau, sẽ không có quá trình chuẩn hoá nào được thực hiện.
Ví dụ:
Period_multipliedBy_ex1.java
// 20 years 10 months 35 days.
Period period = Period.of(20, 10, 35);

Period result = period.multipliedBy(2);

long years = result.get(ChronoUnit.YEARS); // 40
long months = result.get(ChronoUnit.MONTHS); // 20
long days = result.get(ChronoUnit.DAYS); // 70

System.out.printf("%d years, %d months %d days", years, months, days);

16. negated()

// Inherited from ChronoPeriod interface
public Period negated()
Ví dụ:
Period_negated_ex1.java
// 20 years 3 months 15 days.
Period period = Period.of(20, 3, 15);  
System.out.println("period: " + period); // P20Y3M15D

// period2 = 0 - period1
Period period2 = period.negated();
System.out.println("period2: " + period2); // P-20Y-3M-15D (-20 Years, -3 months, -15 days)

17. normalized()

Trả về bản sao của Period này với năm và tháng được chuẩn hoá. Một năm được coi là bằng 12 tháng, sau khi được chuẩn hoá giá trị của tháng sẽ nằm trong phạm vi -11 đến 11.
// Inherited from ChronoPeriod interface
public Period normalized()
Ví dụ:
  • "1 years -25 months 50 days" --> "-1 year -1 months 50 days".
Period_normalized_ex1.java
// 1 years -25 months 50 days.
Period period = Period.of(1, -25, 50);

Period result = period.normalized();

long years = result.get(ChronoUnit.YEARS); // -1
long months = result.get(ChronoUnit.MONTHS); // -1
long days = result.get(ChronoUnit.DAYS); // 50

System.out.printf("%d years, %d months %d days", years, months, days);

18. toTotalMonths()

Trả về tổng số tháng trong Period này bằng cách nhân số năm với 12 và cộng số tháng. Số ngày sẽ bị bỏ qua.
public long toTotalMonths()
Ví dụ:
Period_toTotalMonths_ex1.java
// 1 years 3 months 145 days.
Period period = Period.of(1, 3, 145);  
System.out.println("period: " + period); // P1Y3M145D

long months = period.toTotalMonths();
System.out.println("period.toTotalMonths(): " + months); // 15

19. addTo(Temporal)

Thêm Period này vào một đối tượng Temporal được chỉ định và trả về một đối tượng Temporal mới.
// Inherited from ChronoPeriod interface
public Temporal addTo(Temporal temporal)
Phương thức này tương đương với việc sử dụng phương thức Temporal.plus(TemporalAmount).
// Defined in Temporal interface.
public Temporal plus​(TemporalAmount amount)
Ví dụ:
Period_addTo_ex1.java
// Create Temporal object.
LocalDateTime localDateTime = LocalDateTime.of(2000, 1, 10, 23, 30, 0);
System.out.println("localDateTime: " + localDateTime); // 2000-01-10T23:30

// 1 Year 1 month 25 days.
Period period = Period.of(1, 1, 25);

LocalDateTime newLocalDateTime = (LocalDateTime) period.addTo(localDateTime);
System.out.println("newLocalDateTime: " + newLocalDateTime); // 2001-03-07T23:30

20. subtractFrom(Temporal)

Trừ Period này ra khỏi một đối tượng Temporal được chỉ định và trả về một đối tượng Temporal mới.
// Inherited from ChronoPeriod interface
public Temporal subtractFrom(Temporal temporal)
Phương thức này tương đương với việc sử dụng phương thức Temporal.minus(TemporalAmount).
// Defined in Temporal interface.
public Temporal minus(TemporalAmount amount)
Ví dụ:
Period_subtractFrom_ex1.java
// Create Temporal object.
LocalDateTime localDateTime = LocalDateTime.of(2000, 1, 10, 23, 30, 0);
System.out.println("localDateTime: " + localDateTime); // 2000-01-10T23:30

// 1 Year 1 month 25 days.
Period period = Period.of(1, 1, 25);

LocalDateTime newLocalDateTime = (LocalDateTime) period.subtractFrom(localDateTime);
System.out.println("newLocalDateTime: " + newLocalDateTime); // 1998-11-15T23:30