Java新日期时间包的使用
参考: unable-to-obtain-localdatetime-from-temporalaccessor-when-parsing-localdatetime
快速开始:
1@SuppressWarnings("all")
2public class JTSimpleIntro {
3 static String DATE_TIME_FORM = "yyyy-MM-dd HH:mm:ss";
4
5 static void parseDateTimeString(String yyyyMMdd_HHmmss) {
6 System.out.println(LocalDateTime.parse(yyyyMMdd_HHmmss));
7 }
8
9 static void parseDateTimeStringWithFormat(String yyyyMMdd_HHmmss) {
10 System.out.println(LocalDateTime
11 .parse(yyyyMMdd_HHmmss,
12 DateTimeFormatter.ofPattern(DATE_TIME_FORM)));
13 }
14
15 static void parseDateString(String yyyyMMdd) {
16 System.out.println(LocalDate.parse(yyyyMMdd));
17 }
18
19 static void parseTimeString(String HHmmss) {
20 System.out.println(LocalTime.parse(HHmmss));
21 }
22
23 public static void main(String[] args) {
24 parseDateTimeString("2012-06-09T13:12:11");
25 parseDateTimeStringWithFormat("2012-06-09 13:12:11");
26 parseDateString("2012-06-06");
27 parseTimeString("13:12:11");
28 }
29}
以下是API示例:
1/**
2 * {@link java.time} 包是jdk8 新增的日期时间包,
3 * 可以完全替代之前的日期时间系统,包括:
4 *
5 * <li>{@link Date}</li>
6 * <li>{@link java.util.Calendar}</li>
7 * <li>{@link java.util.TimeZone}</li>
8 * <li>{@link java.text.DateFormat}</li>
9 * <li>{@link SimpleDateFormat}</li>
10 * <p>
11 * {@link java.time}是全新设计的api,应学习如何使用之。
12 * <p>
13 *
14 * @author wangy
15 * @date 2021-2-2 9:47
16 * @see LocalDateTime
17 */
18public class JTCommonUsage {
19 static String yyyy = "yyyy";
20 static String yyyy_MM = "yyy-MM";
21 static String yyyy_MM_dd = "yyyy-MM-dd";
22 static String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";
23 static String yyyy_MM_dd_HH_mm_ss_SSS = "yyyy-MM-dd HH:mm:ss.SSS";
24
25 /**
26 * If the pattern like 'yyyy', result {@link LocalDateTime}
27 * could be like 'yyyy-01-01 00:00:00'.<br>
28 * If the pattern like 'yyyy-MM', result {@link LocalDateTime}
29 * could be like 'yyyy-MM-01 00:00:00'.<br>
30 * If the pattern like 'yyyy-MM-dd', result {@link LocalDateTime}
31 * could be like 'yyyy-MM-dd 00:00:00'.<br>
32 * Other patterns acts the same.
33 * <p>
34 *
35 * <b>Important:</b> the pattern and the the
36 * {@link LocalDateTime#parse(CharSequence, DateTimeFormatter)}
37 * method's input
38 * {@link CharSequence} must match.
39 * e.g. The following method call will throw
40 * {@link java.time.format.DateTimeParseException}:
41 *
42 * <pre>
43 * LocalDateTime localDateTime = LocalDateTime
44 * .parse("2021", dtfBuilder("yyyy-MM"));
45 * </pre>
46 *
47 * @param pattern the string pattern
48 * @see DateTimeFormatter javadoc
49 * @see LocalDateTime#parse(CharSequence, DateTimeFormatter)
50 */
51 static DateTimeFormatter dtfBuilder(String pattern) {
52 return new DateTimeFormatterBuilder()
53 .appendPattern(pattern)
54 .parseDefaulting(ChronoField.YEAR_OF_ERA,
55 LocalDateTime.now().getYear())
56 .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
57 .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
58 .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
59 .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
60 .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
61 .parseDefaulting(ChronoField.NANO_OF_SECOND, 0)
62 .toFormatter();
63 }
64
65 static SimpleDateFormat sdfBuilder(String pattern) {
66 return new SimpleDateFormat(pattern);
67 }
68
69 /**
70 * solution1:
71 * Get yyyy-MM-dd 00:00:00, start of the day.<br>
72 * If you use yyyy-MM-dd as parameter
73 */
74 static Date getStartOfDay() {
75 LocalDateTime localDateTime = LocalDateTime
76 .parse("2021-02-02",
77 dtfBuilder(yyyy_MM_dd));
78 Instant instant = localDateTime
79 .atZone(ZoneId.systemDefault())
80 .toInstant();
81 return Date.from(instant);
82 }
83
84 /**
85 * solution2:
86 * get yyyy-MM-dd 00:00:00, start of the day.<br>
87 * If you use yyyy-MM-dd as parameter<br>
88 * <p>
89 * Using {@link LocalDate#atStartOfDay()}
90 *
91 * @param dateString datePattern like 2012-09-08
92 */
93 static Date getStartOfDay(String dateString) throws ParseException {
94 // 由于dtfBuilder的设置 这里的时间已经是 00:00:00
95 LocalDate localDate = LocalDate
96 .parse(dateString, dtfBuilder(yyyy_MM_dd));
97 ZonedDateTime zonedDateTime = localDate
98 .atStartOfDay(ZoneId.systemDefault());
99 return Date.from(zonedDateTime.toInstant());
100 // return
101 // sdfBuilder()
102 // .parse(zonedDateTime
103 // .format(dtfBuilder(yyyy_MM_dd_HH_mm_ss)));
104 }
105
106 /**
107 *
108 */
109 static Date getStartOfDay(LocalDate localDate) {
110 ZonedDateTime zonedDateTime = localDate
111 .atStartOfDay(ZoneId.systemDefault());
112
113 LocalDateTime localDateTime = localDate.atStartOfDay();
114 Instant instant = localDateTime
115 .toInstant(ZoneOffset.of("+8"));
116 // return Date.from(zonedDateTime.toInstant());
117 return Date.from(instant);
118 }
119
120 /**
121 * Get yyyy-MM-dd 23:59:59.999, end of the day.<br>
122 * By using {@link LocalDateTime#plus(long, TemporalUnit)}
123 */
124 static Date getEndOfDay() {
125 // 由于dtfBuilder的设置 这里的时间已经是 00:00:00
126 LocalDateTime localDateTime = LocalDateTime
127 .parse("2020-12-21", dtfBuilder(yyyy_MM_dd));
128
129 // plusXxx()方法没有提供毫秒/微秒的相应方法,直接到纳秒;
130 // 相应的,可以使用plus方法指定单位
131 localDateTime = localDateTime
132 .plusHours(23)
133 .plusMinutes(59)
134 .plusSeconds(59)
135 .plusNanos(999_999_999);
136
137 /*
138 * 好方法,将其下级单位的值清零
139 * ChronoUnit.DAYS: 清零hh:mm:ss.SSS
140 * 最大单位 DAYS,也就是说此方法只能用来清零时间
141 */
142 localDateTime = localDateTime.truncatedTo(ChronoUnit.DAYS);
143 localDateTime = localDateTime
144 .plus(23, ChronoUnit.HOURS)
145 .plus(59, ChronoUnit.MINUTES)
146 .plus(59, ChronoUnit.SECONDS)
147 .plus(999, ChronoUnit.MILLIS);
148 return Date.from(
149 localDateTime
150 .atZone(ZoneId.systemDefault())
151 .toInstant());
152 }
153
154 /**
155 * Get yyyy-MM-dd 23:59:59.999, end of the day.<br>
156 * By using {@link LocalDate#atTime(LocalTime)}
157 *
158 * @param dateString date pattern like '2012-09-18'
159 */
160 static Date getEndOfDay(String dateString) {
161 LocalDate localDate = LocalDate
162 .parse(dateString, dtfBuilder(yyyy_MM_dd));
163 // localDate.
164 LocalDateTime localDateTime = localDate
165 .atTime(23,
166 59,
167 59,
168 999_999_999);
169 return Date.from(localDateTime
170 .atZone(ZoneId.systemDefault())
171 .toInstant());
172
173 }
174
175 /**
176 * Get first day of month
177 *
178 * @param dateString pattern like '2020-10-25'
179 * @return
180 */
181 static Date getFirstDayOfMonth(String dateString) {
182 LocalDateTime localDateTime = LocalDateTime
183 .parse(dateString, dtfBuilder(yyyy_MM_dd));
184 localDateTime = localDateTime.withDayOfMonth(1);
185 return Date.from(localDateTime
186 .atZone(ZoneId.systemDefault())
187 .toInstant());
188 }
189
190 /**
191 * Get the first day of year.
192 *
193 * @param yearString pattern like '2012'
194 */
195 static Date getFirstDayOfYear(String yearString) {
196 LocalDateTime localDateTime = LocalDateTime
197 .parse(yearString, dtfBuilder(yyyy));
198 return Date.from(localDateTime
199 .atZone(ZoneId.systemDefault())
200 .toInstant());
201 }
202
203 public static void main(String[] args) throws ParseException {
204 System.out.println(sdfBuilder(yyyy_MM_dd_HH_mm_ss)
205 .format(getStartOfDay()));
206
207 System.out.println(sdfBuilder(yyyy_MM_dd_HH_mm_ss)
208 .format(getStartOfDay("2021-02-02")));
209
210 System.out.println(sdfBuilder(yyyy_MM_dd_HH_mm_ss_SSS)
211 .format(getStartOfDay(
212 LocalDate
213 .parse("2021-02-22",
214 dtfBuilder(yyyy_MM_dd)))));
215
216 System.out.println(sdfBuilder(yyyy_MM_dd_HH_mm_ss_SSS)
217 .format(getEndOfDay()));
218
219 System.out.println(sdfBuilder(yyyy_MM_dd_HH_mm_ss_SSS)
220 .format(getEndOfDay("2020-12-21")));
221
222 System.out.println(sdfBuilder(yyyy_MM_dd)
223 .format(getFirstDayOfMonth("2020-12-18")));
224
225 System.out.println(sdfBuilder(yyyy_MM_dd_HH_mm_ss)
226 .format(getFirstDayOfYear("2012")));
227 }
228}