#1727 - Refactor internals to use Instant for json parse on date time types (#1728)

This commit is contained in:
Rob Bygrave
2019-06-10 16:16:04 +12:00
committed by GitHub
parent e26a38ecaa
commit 6af5fae8e9
20 changed files with 237 additions and 53 deletions
@@ -0,0 +1,21 @@
package io.ebeaninternal.server.type;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
class IsoJsonDateTimeParser {
private static final DateTimeFormatter ISO_MILLIS = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendInstant(3)
.toFormatter();
static Instant parseIso(String jsonDateTime) {
return Instant.parse(jsonDateTime);
}
static String formatIso(Instant value) {
return ISO_MILLIS.format(value);
}
}
@@ -1,9 +1,9 @@
package io.ebeaninternal.server.type;
import io.ebean.config.JsonConfig;
import io.ebeanservice.docstore.api.mapping.DocPropertyType;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import io.ebean.config.JsonConfig;
import io.ebeanservice.docstore.api.mapping.DocPropertyType;
import java.io.DataInput;
import java.io.DataOutput;
@@ -12,15 +12,15 @@ import java.math.BigDecimal;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.Instant;
import static io.ebeaninternal.server.type.IsoJsonDateTimeParser.parseIso;
/**
* Base type for DateTime types.
*/
public abstract class ScalarTypeBaseDateTime<T> extends ScalarTypeBase<T> {
protected final UtilDateTimeParser dateTimeParser = new UtilDateTimeParser();
protected final JsonConfig.DateTime mode;
public ScalarTypeBaseDateTime(JsonConfig.DateTime mode, Class<T> type, boolean jdbcNative, int jdbcType) {
@@ -43,6 +43,11 @@ public abstract class ScalarTypeBaseDateTime<T> extends ScalarTypeBase<T> {
*/
public abstract T convertFromTimestamp(Timestamp ts);
/**
* Convert to the value from a Instant.
*/
public abstract T convertFromInstant(Instant ts);
/**
* Convert from epoch millis to the value.
*/
@@ -64,6 +69,13 @@ public abstract class ScalarTypeBaseDateTime<T> extends ScalarTypeBase<T> {
*/
protected abstract String toJsonISO8601(T value);
/**
* Convert the value to ISO8601 format.
*/
protected T fromJsonISO8601(String value) {
return convertFromInstant(parseIso(value));
}
@Override
public void bind(DataBind b, T value) throws SQLException {
if (value == null) {
@@ -104,8 +116,7 @@ public abstract class ScalarTypeBaseDateTime<T> extends ScalarTypeBase<T> {
return convertFromTimestamp(timestamp);
}
default: {
String jsonDateTime = parser.getText();
return convertFromTimestamp(dateTimeParser.parse(jsonDateTime));
return fromJsonISO8601(parser.getText());
}
}
}
@@ -7,8 +7,11 @@ import java.sql.Date;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.Instant;
import java.util.Calendar;
import static io.ebeaninternal.server.type.IsoJsonDateTimeParser.formatIso;
/**
* ScalarType for java.util.Calendar.
*/
@@ -48,6 +51,13 @@ public class ScalarTypeCalendar extends ScalarTypeBaseDateTime<Calendar> {
return calendar;
}
@Override
public Calendar convertFromInstant(Instant ts) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(ts.toEpochMilli());
return calendar;
}
@Override
protected String toJsonNanos(Calendar value) {
return String.valueOf(value.getTime());
@@ -55,7 +65,7 @@ public class ScalarTypeCalendar extends ScalarTypeBaseDateTime<Calendar> {
@Override
protected String toJsonISO8601(Calendar value) {
return dateTimeParser.format(value.getTime());
return formatIso(value.toInstant());
}
@Override
@@ -25,6 +25,11 @@ public class ScalarTypeInstant extends ScalarTypeBaseDateTime<Instant> {
return value.toString();
}
@Override
protected Instant fromJsonISO8601(String value) {
return Instant.parse(value);
}
@Override
public long convertToMillis(Instant value) {
return value.toEpochMilli();
@@ -40,6 +45,11 @@ public class ScalarTypeInstant extends ScalarTypeBaseDateTime<Instant> {
return ts.toInstant();
}
@Override
public Instant convertFromInstant(Instant ts) {
return ts;
}
@Override
public Timestamp convertToTimestamp(Instant t) {
return Timestamp.from(t);
@@ -6,6 +6,7 @@ import org.joda.time.DateTime;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.Instant;
/**
* ScalarType for Joda DateTime. This maps to a JDBC Timestamp.
@@ -41,6 +42,11 @@ public class ScalarTypeJodaDateTime extends ScalarTypeBaseDateTime<DateTime> {
return new DateTime(ts.getTime());
}
@Override
public DateTime convertFromInstant(Instant ts) {
return new DateTime(ts.toEpochMilli());
}
@Override
public Timestamp convertToTimestamp(DateTime t) {
return new Timestamp(t.getMillis());
@@ -6,6 +6,7 @@ import org.joda.time.LocalDateTime;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.Instant;
/**
* ScalarType for Joda LocalDateTime. This maps to a JDBC Timestamp.
@@ -31,7 +32,6 @@ public class ScalarTypeJodaLocalDateTime extends ScalarTypeBaseDateTime<LocalDat
return value.toDateTime().getMillis();
}
@Override
public LocalDateTime convertFromMillis(long systemTimeMillis) {
return new LocalDateTime(systemTimeMillis);
@@ -42,6 +42,11 @@ public class ScalarTypeJodaLocalDateTime extends ScalarTypeBaseDateTime<LocalDat
return new LocalDateTime(ts.getTime());
}
@Override
public LocalDateTime convertFromInstant(Instant ts) {
return new LocalDateTime(ts.toEpochMilli());
}
@Override
public Timestamp convertToTimestamp(LocalDateTime t) {
return new Timestamp(t.toDateTime().getMillis());
@@ -4,6 +4,7 @@ import io.ebean.config.JsonConfig;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
@@ -41,6 +42,11 @@ public class ScalarTypeLocalDateTime extends ScalarTypeBaseDateTime<LocalDateTim
return timestamp.toLocalDateTime();
}
@Override
public LocalDateTime convertFromInstant(Instant ts) {
return LocalDateTime.ofInstant(ts, ZoneId.systemDefault());
}
@Override
public Timestamp convertToTimestamp(LocalDateTime dateTime) {
return Timestamp.valueOf(dateTime);
@@ -8,6 +8,8 @@ import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import static io.ebeaninternal.server.type.IsoJsonDateTimeParser.formatIso;
/**
* ScalarType for java.sql.Timestamp.
*/
@@ -24,7 +26,7 @@ public class ScalarTypeOffsetDateTime extends ScalarTypeBaseDateTime<OffsetDateT
@Override
protected String toJsonISO8601(OffsetDateTime value) {
return value.toInstant().toString();
return formatIso(value.toInstant());
}
@Override
@@ -34,12 +36,17 @@ public class ScalarTypeOffsetDateTime extends ScalarTypeBaseDateTime<OffsetDateT
@Override
public OffsetDateTime convertFromMillis(long systemTimeMillis) {
return OffsetDateTime.ofInstant(Instant.ofEpochMilli(systemTimeMillis), ZoneId.systemDefault());
return convertFromInstant(Instant.ofEpochMilli(systemTimeMillis));
}
@Override
public OffsetDateTime convertFromTimestamp(Timestamp ts) {
return OffsetDateTime.ofInstant(ts.toInstant(), ZoneId.systemDefault());
return convertFromInstant(ts.toInstant());
}
@Override
public OffsetDateTime convertFromInstant(Instant ts) {
return OffsetDateTime.ofInstant(ts, ZoneId.systemDefault());
}
@Override
@@ -6,6 +6,9 @@ import io.ebeaninternal.server.core.BasicTypeConverter;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.Instant;
import static io.ebeaninternal.server.type.IsoJsonDateTimeParser.formatIso;
/**
* ScalarType for java.sql.Timestamp.
@@ -23,7 +26,7 @@ public class ScalarTypeTimestamp extends ScalarTypeBaseDateTime<Timestamp> {
@Override
protected String toJsonISO8601(Timestamp value) {
return dateTimeParser.format(value);
return formatIso(value.toInstant());
}
@Override
@@ -41,6 +44,11 @@ public class ScalarTypeTimestamp extends ScalarTypeBaseDateTime<Timestamp> {
return ts;
}
@Override
public Timestamp convertFromInstant(Instant ts) {
return Timestamp.from(ts);
}
@Override
public Timestamp convertToTimestamp(Timestamp t) {
return t;
@@ -6,8 +6,11 @@ import io.ebeaninternal.server.core.BasicTypeConverter;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.Instant;
import java.util.Date;
import static io.ebeaninternal.server.type.IsoJsonDateTimeParser.formatIso;
/**
* ScalarType for java.util.Date.
*/
@@ -26,7 +29,7 @@ public class ScalarTypeUtilDate {
@Override
protected String toJsonISO8601(Date value) {
return dateTimeParser.format(value);
return formatIso(value.toInstant());
}
@Override
@@ -69,6 +72,11 @@ public class ScalarTypeUtilDate {
return new java.util.Date(ts.getTime());
}
@Override
public Date convertFromInstant(Instant ts) {
return new java.util.Date(ts.toEpochMilli());
}
@Override
public Timestamp convertToTimestamp(Date date) {
return new Timestamp(date.getTime());
@@ -34,12 +34,17 @@ public class ScalarTypeZonedDateTime extends ScalarTypeBaseDateTime<ZonedDateTim
@Override
public ZonedDateTime convertFromMillis(long systemTimeMillis) {
return ZonedDateTime.ofInstant(Instant.ofEpochMilli(systemTimeMillis), ZoneId.systemDefault());
return convertFromInstant(Instant.ofEpochMilli(systemTimeMillis));
}
@Override
public ZonedDateTime convertFromTimestamp(Timestamp ts) {
return ZonedDateTime.ofInstant(ts.toInstant(), ZoneId.systemDefault());
return convertFromInstant(ts.toInstant());
}
@Override
public ZonedDateTime convertFromInstant(Instant ts) {
return ZonedDateTime.ofInstant(ts, ZoneId.systemDefault());
}
@Override
@@ -1,28 +0,0 @@
package io.ebeaninternal.server.type;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.util.Date;
class UtilDateTimeParser {
private static final DateTimeFormatter ISO_MILLIS = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendInstant(3)
.toFormatter();
public Timestamp parse(String jsonDateTime) {
try {
return Timestamp.from(Instant.parse(jsonDateTime));
} catch (DateTimeParseException e) {
throw new RuntimeException("Error parsing Datetime[" + jsonDateTime + "]", e);
}
}
public String format(Date value) {
return ISO_MILLIS.format(value.toInstant());
}
}