diff --git a/src/main/java/com/googlecode/objectify/impl/translate/BigDecimalTranslatorFactory.java b/src/main/java/com/googlecode/objectify/impl/translate/BigDecimalTranslatorFactory.java
new file mode 100644
index 00000000..373aa470
--- /dev/null
+++ b/src/main/java/com/googlecode/objectify/impl/translate/BigDecimalTranslatorFactory.java
@@ -0,0 +1,27 @@
+package com.googlecode.objectify.impl.translate;
+
+import com.google.cloud.datastore.StringValue;
+import com.google.cloud.datastore.Value;
+import com.google.cloud.datastore.ValueType;
+import java.math.BigDecimal;
+
+/**
+ * Converts java.math.BigDecimal into a java.lang.String.
+ *
+ *
All custom translators must be registered *before* entity classes are registered.
+ */
+public class BigDecimalTranslatorFactory extends SimpleTranslatorFactory {
+ public BigDecimalTranslatorFactory() {
+ super(BigDecimal.class, ValueType.STRING);
+ }
+
+ @Override
+ protected BigDecimal toPojo(Value value) {
+ return new BigDecimal(value.get());
+ }
+
+ @Override
+ protected Value toDatastore(BigDecimal value) {
+ return StringValue.of(value.toString());
+ }
+}
diff --git a/src/main/java/com/googlecode/objectify/impl/translate/InstantTimeTranslatorFactory.java b/src/main/java/com/googlecode/objectify/impl/translate/InstantTimeTranslatorFactory.java
new file mode 100644
index 00000000..6ca00033
--- /dev/null
+++ b/src/main/java/com/googlecode/objectify/impl/translate/InstantTimeTranslatorFactory.java
@@ -0,0 +1,29 @@
+package com.googlecode.objectify.impl.translate;
+
+import com.google.cloud.Timestamp;
+import com.google.cloud.datastore.TimestampValue;
+import com.google.cloud.datastore.Value;
+import com.google.cloud.datastore.ValueType;
+import java.time.Instant;
+
+/**
+ * Converts JSR-310 Instant into a java.util.Date.
+ *
+ * All custom translators must be registered *before* entity classes are registered.
+ */
+public class InstantTimeTranslatorFactory extends SimpleTranslatorFactory {
+ public InstantTimeTranslatorFactory() {
+ super(Instant.class, ValueType.TIMESTAMP);
+ }
+
+ @Override
+ protected Instant toPojo(Value value) {
+ return Instant.ofEpochSecond(value.get().getSeconds()).plusNanos(value.get().getNanos());
+ }
+
+ @Override
+ protected Value toDatastore(Instant value) {
+ return TimestampValue.of(
+ Timestamp.ofTimeSecondsAndNanos(value.getEpochSecond(), value.getNano()));
+ }
+}
diff --git a/src/main/java/com/googlecode/objectify/impl/translate/LocalDateTimeTranslatorFactory.java b/src/main/java/com/googlecode/objectify/impl/translate/LocalDateTimeTranslatorFactory.java
new file mode 100644
index 00000000..e42a70d0
--- /dev/null
+++ b/src/main/java/com/googlecode/objectify/impl/translate/LocalDateTimeTranslatorFactory.java
@@ -0,0 +1,27 @@
+package com.googlecode.objectify.impl.translate;
+
+import com.google.cloud.datastore.StringValue;
+import com.google.cloud.datastore.Value;
+import com.google.cloud.datastore.ValueType;
+import java.time.LocalDateTime;
+
+/**
+ * Converts JSR-310 LocalDateTime into a String.
+ *
+ * All custom translators must be registered *before* entity classes are registered.
+ */
+public class LocalDateTimeTranslatorFactory extends SimpleTranslatorFactory {
+ public LocalDateTimeTranslatorFactory() {
+ super(LocalDateTime.class, ValueType.STRING);
+ }
+
+ @Override
+ protected LocalDateTime toPojo(Value value) {
+ return LocalDateTime.parse(value.get());
+ }
+
+ @Override
+ protected Value toDatastore(LocalDateTime value) {
+ return StringValue.of(value.toString());
+ }
+}
diff --git a/src/main/java/com/googlecode/objectify/impl/translate/LocalDateTranslatorFactory.java b/src/main/java/com/googlecode/objectify/impl/translate/LocalDateTranslatorFactory.java
new file mode 100644
index 00000000..c9b568f4
--- /dev/null
+++ b/src/main/java/com/googlecode/objectify/impl/translate/LocalDateTranslatorFactory.java
@@ -0,0 +1,27 @@
+package com.googlecode.objectify.impl.translate;
+
+import com.google.cloud.datastore.StringValue;
+import com.google.cloud.datastore.Value;
+import com.google.cloud.datastore.ValueType;
+import java.time.LocalDate;
+
+/**
+ * Converts JSR-310 LocalDate into a String.
+ *
+ * All custom translators must be registered *before* entity classes are registered.
+ */
+public class LocalDateTranslatorFactory extends SimpleTranslatorFactory {
+ public LocalDateTranslatorFactory() {
+ super(LocalDate.class, ValueType.STRING);
+ }
+
+ @Override
+ protected LocalDate toPojo(Value value) {
+ return LocalDate.parse(value.get());
+ }
+
+ @Override
+ protected Value toDatastore(LocalDate value) {
+ return StringValue.of(value.toString());
+ }
+}
diff --git a/src/main/java/com/googlecode/objectify/impl/translate/LocaleTranslatorFactory.java b/src/main/java/com/googlecode/objectify/impl/translate/LocaleTranslatorFactory.java
new file mode 100644
index 00000000..1380c9d7
--- /dev/null
+++ b/src/main/java/com/googlecode/objectify/impl/translate/LocaleTranslatorFactory.java
@@ -0,0 +1,27 @@
+package com.googlecode.objectify.impl.translate;
+
+import com.google.cloud.datastore.StringValue;
+import com.google.cloud.datastore.Value;
+import com.google.cloud.datastore.ValueType;
+import java.util.Locale;
+
+/**
+ * Converts java.util.Locale into a java.lang.String.
+ *
+ * All custom translators must be registered *before* entity classes are registered.
+ */
+public class LocaleTranslatorFactory extends SimpleTranslatorFactory {
+ public LocaleTranslatorFactory() {
+ super(Locale.class, ValueType.STRING);
+ }
+
+ @Override
+ protected Locale toPojo(Value value) {
+ return Locale.forLanguageTag(value.get());
+ }
+
+ @Override
+ protected Value toDatastore(Locale value) {
+ return StringValue.of(value.toLanguageTag());
+ }
+}
diff --git a/src/main/java/com/googlecode/objectify/impl/translate/OffsetDateTimeTranslatorFactory.java b/src/main/java/com/googlecode/objectify/impl/translate/OffsetDateTimeTranslatorFactory.java
new file mode 100644
index 00000000..2efc60cb
--- /dev/null
+++ b/src/main/java/com/googlecode/objectify/impl/translate/OffsetDateTimeTranslatorFactory.java
@@ -0,0 +1,35 @@
+package com.googlecode.objectify.impl.translate;
+
+import com.google.cloud.Timestamp;
+import com.google.cloud.datastore.TimestampValue;
+import com.google.cloud.datastore.Value;
+import com.google.cloud.datastore.ValueType;
+import java.time.Instant;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+
+/**
+ * Converts JSR-310 OffsetDateTime into a java.util.Date.
+ *
+ * All custom translators must be registered *before* entity classes are registered.
+ */
+public class OffsetDateTimeTranslatorFactory
+ extends SimpleTranslatorFactory {
+ public OffsetDateTimeTranslatorFactory() {
+ super(OffsetDateTime.class, ValueType.TIMESTAMP);
+ }
+
+ @Override
+ protected OffsetDateTime toPojo(Value value) {
+ return Instant.ofEpochSecond(value.get().getSeconds())
+ .plusNanos(value.get().getNanos())
+ .atZone(ZoneOffset.UTC)
+ .toOffsetDateTime();
+ }
+
+ @Override
+ protected Value toDatastore(OffsetDateTime value) {
+ return TimestampValue.of(
+ Timestamp.ofTimeSecondsAndNanos(value.toEpochSecond(), value.getNano()));
+ }
+}
diff --git a/src/main/java/com/googlecode/objectify/impl/translate/Translators.java b/src/main/java/com/googlecode/objectify/impl/translate/Translators.java
index 7dca42bc..e42e675c 100644
--- a/src/main/java/com/googlecode/objectify/impl/translate/Translators.java
+++ b/src/main/java/com/googlecode/objectify/impl/translate/Translators.java
@@ -33,7 +33,7 @@ public class Translators
/** Where we should insert new translators */
private int insertPoint;
-
+
/** Where we should insert new early translators */
private int earlyInsertPoint;
@@ -87,6 +87,14 @@ public Translators(final ObjectifyFactory fact) {
this.translatorFactories.add(new LatLngTranslatorFactory());
this.translatorFactories.add(new BlobTranslatorFactory());
this.translatorFactories.add(new RawValueTranslatorFactory());
+ this.translatorFactories.add(new BigDecimalTranslatorFactory());
+ this.translatorFactories.add(new InstantTimeTranslatorFactory());
+ this.translatorFactories.add(new LocalDateTranslatorFactory());
+ this.translatorFactories.add(new LocalDateTimeTranslatorFactory());
+ this.translatorFactories.add(new LocaleTranslatorFactory());
+ this.translatorFactories.add(new OffsetDateTimeTranslatorFactory());
+ this.translatorFactories.add(new ZonedDateTimeTranslatorFactory());
+ this.translatorFactories.add(new ZoneIdTranslatorFactory());
this.translatorFactories.add(new ObjectTranslatorFactory(this));
// LAST! It catches everything.
@@ -104,7 +112,7 @@ public void add(final TranslatorFactory, ?> trans) {
this.translatorFactories.add(insertPoint, trans);
insertPoint++;
}
-
+
/**
* Add a new translator to the beginning of the list, before all other translators
* except other translators that have been added early.
@@ -151,4 +159,4 @@ public Translator
> getRoot(final Class
clazz) {
throw new IllegalArgumentException("Don't know how to translate " + tk.getType() + " with annotations " + Arrays.toString(tk.getAnnotations()));
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/googlecode/objectify/impl/translate/ZoneIdTranslatorFactory.java b/src/main/java/com/googlecode/objectify/impl/translate/ZoneIdTranslatorFactory.java
new file mode 100644
index 00000000..df20bbfd
--- /dev/null
+++ b/src/main/java/com/googlecode/objectify/impl/translate/ZoneIdTranslatorFactory.java
@@ -0,0 +1,27 @@
+package com.googlecode.objectify.impl.translate;
+
+import com.google.cloud.datastore.StringValue;
+import com.google.cloud.datastore.Value;
+import com.google.cloud.datastore.ValueType;
+import java.time.ZoneId;
+
+/**
+ * Converts JSR-310 ZoneId into a java.lang.String.
+ *
+ *
All custom translators must be registered *before* entity classes are registered.
+ */
+public class ZoneIdTranslatorFactory extends SimpleTranslatorFactory {
+ public ZoneIdTranslatorFactory() {
+ super(ZoneId.class, ValueType.STRING);
+ }
+
+ @Override
+ protected ZoneId toPojo(Value value) {
+ return ZoneId.of(value.get());
+ }
+
+ @Override
+ protected Value toDatastore(ZoneId value) {
+ return StringValue.of(value.getId());
+ }
+}
diff --git a/src/main/java/com/googlecode/objectify/impl/translate/ZonedDateTimeTranslatorFactory.java b/src/main/java/com/googlecode/objectify/impl/translate/ZonedDateTimeTranslatorFactory.java
new file mode 100644
index 00000000..b6a0d490
--- /dev/null
+++ b/src/main/java/com/googlecode/objectify/impl/translate/ZonedDateTimeTranslatorFactory.java
@@ -0,0 +1,34 @@
+package com.googlecode.objectify.impl.translate;
+
+import com.google.cloud.Timestamp;
+import com.google.cloud.datastore.TimestampValue;
+import com.google.cloud.datastore.Value;
+import com.google.cloud.datastore.ValueType;
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+
+/**
+ * Converts JSR-310 ZonedDateTime into a java.util.Date.
+ *
+ * All custom translators must be registered *before* entity classes are registered.
+ */
+public class ZonedDateTimeTranslatorFactory
+ extends SimpleTranslatorFactory {
+ public ZonedDateTimeTranslatorFactory() {
+ super(ZonedDateTime.class, ValueType.TIMESTAMP);
+ }
+
+ @Override
+ protected ZonedDateTime toPojo(Value value) {
+ return Instant.ofEpochSecond(value.get().getSeconds())
+ .plusNanos(value.get().getNanos())
+ .atZone(ZoneOffset.UTC);
+ }
+
+ @Override
+ protected Value toDatastore(ZonedDateTime value) {
+ return TimestampValue.of(
+ Timestamp.ofTimeSecondsAndNanos(value.toEpochSecond(), value.getNano()));
+ }
+}