Skip to content

Commit 9bc4bee

Browse files
authored
DATAES-953 - DateTimeException on converting Instant or Date to custom format.
Original PR: #538
1 parent 0ce2c49 commit 9bc4bee

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverter.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@
1818
import java.lang.reflect.InvocationTargetException;
1919
import java.lang.reflect.Method;
2020
import java.time.Instant;
21+
import java.time.ZonedDateTime;
2122
import java.time.temporal.TemporalAccessor;
2223
import java.util.Date;
2324
import java.util.concurrent.ConcurrentHashMap;
2425

2526
import org.elasticsearch.common.time.DateFormatter;
27+
import org.elasticsearch.common.time.DateFormatters;
2628
import org.springframework.data.elasticsearch.annotations.DateFormat;
2729
import org.springframework.util.Assert;
2830

@@ -103,10 +105,10 @@ public String format(Date date) {
103105
* @return the new created object
104106
*/
105107
public <T extends TemporalAccessor> T parse(String input, Class<T> type) {
106-
TemporalAccessor accessor = dateFormatter.parse(input);
108+
ZonedDateTime zonedDateTime = DateFormatters.from(dateFormatter.parse(input));
107109
try {
108110
Method method = type.getMethod("from", TemporalAccessor.class);
109-
Object o = method.invoke(null, accessor);
111+
Object o = method.invoke(null, zonedDateTime);
110112
return type.cast(o);
111113
} catch (NoSuchMethodException e) {
112114
throw new ConversionException("no 'from' factory method found in class " + type.getName());
@@ -122,6 +124,7 @@ public <T extends TemporalAccessor> T parse(String input, Class<T> type) {
122124
* @return the new created object
123125
*/
124126
public Date parse(String input) {
125-
return new Date(Instant.from(dateFormatter.parse(input)).toEpochMilli());
127+
ZonedDateTime zonedDateTime = DateFormatters.from(dateFormatter.parse(input));
128+
return new Date(Instant.from(zonedDateTime).toEpochMilli());
126129
}
127130
}

src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.util.Date;
1111
import java.util.GregorianCalendar;
1212

13+
import org.junit.jupiter.api.DisplayName;
1314
import org.junit.jupiter.api.Test;
1415
import org.junit.jupiter.params.ParameterizedTest;
1516
import org.junit.jupiter.params.provider.EnumSource;
@@ -98,4 +99,36 @@ void shouldConvertInstantToString() {
9899

99100
assertThat(formatted).isEqualTo("1234568901234");
100101
}
102+
103+
@Test // DATAES-953
104+
@DisplayName("should write and read Date with custom format")
105+
void shouldWriteAndReadDateWithCustomFormat() {
106+
107+
// only seconds as the format string does not store millis
108+
long currentTimeSeconds = System.currentTimeMillis() / 1_000;
109+
Date date = new Date(currentTimeSeconds * 1_000);
110+
111+
ElasticsearchDateConverter converter = ElasticsearchDateConverter.of("uuuu-MM-dd HH:mm:ss");
112+
113+
String formatted = converter.format(date);
114+
Date parsed = converter.parse(formatted);
115+
116+
assertThat(parsed).isEqualTo(date);
117+
}
118+
119+
@Test // DATAES-953
120+
@DisplayName("should write and read Instant with custom format")
121+
void shouldWriteAndReadInstantWithCustomFormat() {
122+
123+
// only seconds as the format string does not store millis
124+
long currentTimeSeconds = System.currentTimeMillis() / 1_000;
125+
Instant instant = Instant.ofEpochSecond(currentTimeSeconds);
126+
127+
ElasticsearchDateConverter converter = ElasticsearchDateConverter.of("uuuu-MM-dd HH:mm:ss");
128+
129+
String formatted = converter.format(instant);
130+
Instant parsed = converter.parse(formatted, Instant.class);
131+
132+
assertThat(parsed).isEqualTo(instant);
133+
}
101134
}

0 commit comments

Comments
 (0)