-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPeriodDemo.java
More file actions
106 lines (94 loc) · 3.6 KB
/
Copy pathPeriodDemo.java
File metadata and controls
106 lines (94 loc) · 3.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package Phase8_PracticalAPIs.DateAndTime;
import java.time.LocalDate;
import java.time.Period;
import java.time.temporal.ChronoUnit;
/**
* Period — a Calendar-Length Difference
* -------------------------------------
* Period represents an interval in YEARS, MONTHS, and DAYS — the units
* humans use to talk about ages and trial periods.
* <p>
*
* P1Y2M3D = 1 year 2 months 3 days
* P10D = 10 days
* <p>
*
* Unlike Duration, Period is CALENDAR-AWARE: adding 1 month to Jan 31
* does NOT give Feb 31. It clamps to the last valid day.
* <p>
*
* Construction
* ------------
* Period.ofDays / ofWeeks / ofMonths / ofYears
* Period.of(y, m, d)
* Period.between(start, end) - LocalDate to LocalDate
* Period.parse("P1Y2M3D")
* <p>
*
* Arithmetic
* ----------
* plus / minus / multipliedBy / negated
* normalized() - rolls 13 months into 1Y1M
* <p>
*
* Accessors
* ---------
* getYears() / getMonths() / getDays()
* isZero() / isNegative()
* <p>
*
* Common use cases
* ----------------
* - "How old is someone?" -> Period.between(birthday, today).getYears()
* - Trial / lease periods.
* - Recurring schedules expressed in months / years.
* <p>
*
* The Jan 31 + 1 month puzzle
* ---------------------------
* LocalDate.of(2026, 1, 31).plus(Period.ofMonths(1)) -> 2026-02-28
* The library "clamps" overflow to the last valid day. Stable, but
* non-commutative: adding twice doesn't always equal adding the sum.
*/
public class PeriodDemo {
public static void main(String[] args) {
section("1) Construction");
Period p1 = Period.ofMonths(3);
Period p2 = Period.of(1, 2, 3);
Period p3 = Period.parse("P1Y2M3D");
System.out.println("p1 = " + p1);
System.out.println("p2 = " + p2);
System.out.println("p3 = " + p3);
section("2) Period.between(start, end)");
LocalDate birthday = LocalDate.of(1990, 6, 15);
LocalDate today = LocalDate.now();
Period age = Period.between(birthday, today);
System.out.println("age = " + age.getYears() + "y "
+ age.getMonths() + "m " + age.getDays() + "d");
section("3) Adding a Period to a LocalDate");
LocalDate trialEnd = today.plus(Period.ofDays(30));
LocalDate anniv = today.plus(Period.ofYears(1));
System.out.println("30-day trial ends = " + trialEnd);
System.out.println("1-year anniv = " + anniv);
section("4) Jan 31 + 1 month → Feb 28 (or 29 in leap)");
LocalDate jan31 = LocalDate.of(2026, 1, 31);
System.out.println("Jan 31 +1M = " + jan31.plusMonths(1));
// adding twice is not the same as adding the sum:
System.out.println("Jan 31 +1M +1M = " + jan31.plusMonths(1).plusMonths(1));
System.out.println("Jan 31 +2M = " + jan31.plusMonths(2));
section("5) normalized()");
Period weird = Period.of(0, 14, 5); // 14 months
System.out.println("weird = " + weird);
System.out.println("weird.normalized = " + weird.normalized());
section("6) Don't confuse calendar with clock");
// ChronoUnit.DAYS.between gives EXACT days; period gives years/months/days.
long calendarDays = ChronoUnit.DAYS.between(birthday, today);
System.out.println("days alive = " + calendarDays);
// The Period above said e.g. 35y 11m 5d — same range, different shape.
section("done");
}
private static void section(String title) {
System.out.println();
System.out.println("=== " + title + " ===");
}
}