1
16 package org.springframework.data.convert;
17
18 import static java.time.Instant.*;
19 import static java.time.LocalDateTime.*;
20 import static java.time.ZoneId.*;
21
22 import java.time.Duration;
23 import java.time.Instant;
24 import java.time.LocalDate;
25 import java.time.LocalDateTime;
26 import java.time.LocalTime;
27 import java.time.Period;
28 import java.time.ZoneId;
29 import java.time.format.DateTimeFormatter;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Collection;
33 import java.util.Collections;
34 import java.util.Date;
35 import java.util.List;
36
37 import javax.annotation.Nonnull;
38
39 import org.springframework.core.convert.converter.Converter;
40 import org.springframework.lang.NonNull;
41 import org.springframework.util.ClassUtils;
42
43
52 public abstract class Jsr310Converters {
53
54 private static final boolean JAVA_8_IS_PRESENT = ClassUtils.isPresent("java.time.LocalDateTime",
55 Jsr310Converters.class.getClassLoader());
56 private static final List<Class<?>> CLASSES = Arrays.asList(LocalDateTime.class, LocalDate.class, LocalTime.class,
57 Instant.class, ZoneId.class, Duration.class, Period.class);
58
59
64 public static Collection<Converter<?, ?>> getConvertersToRegister() {
65
66 if (!JAVA_8_IS_PRESENT) {
67 return Collections.emptySet();
68 }
69
70 List<Converter<?, ?>> converters = new ArrayList<>();
71 converters.add(DateToLocalDateTimeConverter.INSTANCE);
72 converters.add(LocalDateTimeToDateConverter.INSTANCE);
73 converters.add(DateToLocalDateConverter.INSTANCE);
74 converters.add(LocalDateToDateConverter.INSTANCE);
75 converters.add(DateToLocalTimeConverter.INSTANCE);
76 converters.add(LocalTimeToDateConverter.INSTANCE);
77 converters.add(DateToInstantConverter.INSTANCE);
78 converters.add(InstantToDateConverter.INSTANCE);
79 converters.add(LocalDateTimeToInstantConverter.INSTANCE);
80 converters.add(InstantToLocalDateTimeConverter.INSTANCE);
81 converters.add(ZoneIdToStringConverter.INSTANCE);
82 converters.add(StringToZoneIdConverter.INSTANCE);
83 converters.add(DurationToStringConverter.INSTANCE);
84 converters.add(StringToDurationConverter.INSTANCE);
85 converters.add(PeriodToStringConverter.INSTANCE);
86 converters.add(StringToPeriodConverter.INSTANCE);
87 converters.add(StringToLocalDateConverter.INSTANCE);
88 converters.add(StringToLocalDateTimeConverter.INSTANCE);
89 converters.add(StringToInstantConverter.INSTANCE);
90
91 return converters;
92 }
93
94 public static boolean supports(Class<?> type) {
95
96 if (!JAVA_8_IS_PRESENT) {
97 return false;
98 }
99
100 return CLASSES.contains(type);
101 }
102
103 @ReadingConverter
104 public static enum DateToLocalDateTimeConverter implements Converter<Date, LocalDateTime> {
105
106 INSTANCE;
107
108 @Nonnull
109 @Override
110 public LocalDateTime convert(Date source) {
111 return ofInstant(source.toInstant(), systemDefault());
112 }
113 }
114
115 @WritingConverter
116 public static enum LocalDateTimeToDateConverter implements Converter<LocalDateTime, Date> {
117
118 INSTANCE;
119
120 @Nonnull
121 @Override
122 public Date convert(LocalDateTime source) {
123 return Date.from(source.atZone(systemDefault()).toInstant());
124 }
125 }
126
127 @ReadingConverter
128 public static enum DateToLocalDateConverter implements Converter<Date, LocalDate> {
129
130 INSTANCE;
131
132 @Nonnull
133 @Override
134 public LocalDate convert(Date source) {
135 return ofInstant(ofEpochMilli(source.getTime()), systemDefault()).toLocalDate();
136 }
137 }
138
139 @WritingConverter
140 public static enum LocalDateToDateConverter implements Converter<LocalDate, Date> {
141
142 INSTANCE;
143
144 @Nonnull
145 @Override
146 public Date convert(LocalDate source) {
147 return Date.from(source.atStartOfDay(systemDefault()).toInstant());
148 }
149 }
150
151 @ReadingConverter
152 public static enum DateToLocalTimeConverter implements Converter<Date, LocalTime> {
153
154 INSTANCE;
155
156 @Nonnull
157 @Override
158 public LocalTime convert(Date source) {
159 return ofInstant(ofEpochMilli(source.getTime()), systemDefault()).toLocalTime();
160 }
161 }
162
163 @WritingConverter
164 public static enum LocalTimeToDateConverter implements Converter<LocalTime, Date> {
165
166 INSTANCE;
167
168 @Nonnull
169 @Override
170 public Date convert(LocalTime source) {
171 return Date.from(source.atDate(LocalDate.now()).atZone(systemDefault()).toInstant());
172 }
173 }
174
175 @ReadingConverter
176 public static enum DateToInstantConverter implements Converter<Date, Instant> {
177
178 INSTANCE;
179
180 @Nonnull
181 @Override
182 public Instant convert(Date source) {
183 return source.toInstant();
184 }
185 }
186
187 @WritingConverter
188 public static enum InstantToDateConverter implements Converter<Instant, Date> {
189
190 INSTANCE;
191
192 @Nonnull
193 @Override
194 public Date convert(Instant source) {
195 return Date.from(source);
196 }
197 }
198
199 @ReadingConverter
200 public static enum LocalDateTimeToInstantConverter implements Converter<LocalDateTime, Instant> {
201
202 INSTANCE;
203
204 @Nonnull
205 @Override
206 public Instant convert(LocalDateTime source) {
207 return source.atZone(systemDefault()).toInstant();
208 }
209 }
210
211 @ReadingConverter
212 public static enum InstantToLocalDateTimeConverter implements Converter<Instant, LocalDateTime> {
213
214 INSTANCE;
215
216 @Nonnull
217 @Override
218 public LocalDateTime convert(Instant source) {
219 return LocalDateTime.ofInstant(source, systemDefault());
220 }
221 }
222
223 @WritingConverter
224 public static enum ZoneIdToStringConverter implements Converter<ZoneId, String> {
225
226 INSTANCE;
227
228 @Nonnull
229 @Override
230 public String convert(ZoneId source) {
231 return source.toString();
232 }
233 }
234
235 @ReadingConverter
236 public static enum StringToZoneIdConverter implements Converter<String, ZoneId> {
237
238 INSTANCE;
239
240 @Nonnull
241 @Override
242 public ZoneId convert(String source) {
243 return ZoneId.of(source);
244 }
245 }
246
247 @WritingConverter
248 public static enum DurationToStringConverter implements Converter<Duration, String> {
249
250 INSTANCE;
251
252 @Nonnull
253 @Override
254 public String convert(Duration duration) {
255 return duration.toString();
256 }
257 }
258
259 @ReadingConverter
260 public static enum StringToDurationConverter implements Converter<String, Duration> {
261
262 INSTANCE;
263
264 @Nonnull
265 @Override
266 public Duration convert(String s) {
267 return Duration.parse(s);
268 }
269 }
270
271 @WritingConverter
272 public static enum PeriodToStringConverter implements Converter<Period, String> {
273
274 INSTANCE;
275
276 @Nonnull
277 @Override
278 public String convert(Period period) {
279 return period.toString();
280 }
281 }
282
283 @ReadingConverter
284 public static enum StringToPeriodConverter implements Converter<String, Period> {
285
286 INSTANCE;
287
288 @Nonnull
289 @Override
290 public Period convert(String s) {
291 return Period.parse(s);
292 }
293 }
294
295 @ReadingConverter
296 public static enum StringToLocalDateConverter implements Converter<String, LocalDate> {
297
298 INSTANCE;
299
300
304 @NonNull
305 @Override
306 public LocalDate convert(String source) {
307 return LocalDate.parse(source, DateTimeFormatter.ISO_DATE);
308 }
309 }
310
311 @ReadingConverter
312 public static enum StringToLocalDateTimeConverter implements Converter<String, LocalDateTime> {
313
314 INSTANCE;
315
316
320 @NonNull
321 @Override
322 public LocalDateTime convert(String source) {
323 return LocalDateTime.parse(source, DateTimeFormatter.ISO_DATE_TIME);
324 }
325 }
326
327 @ReadingConverter
328 public static enum StringToInstantConverter implements Converter<String, Instant> {
329
330 INSTANCE;
331
332
336 @NonNull
337 @Override
338 public Instant convert(String source) {
339 return Instant.parse(source);
340 }
341 }
342 }
343