38

I'm using GSON to serialise some object graphs to JSON. These objects graphs use Joda Time entities (DateTime, LocalTime etc).

The top Google hit for "gson joda" is this page:

It provides source for a type adapter for org.joda.time.DateTime. This link is also what is referenced in the GSON User Guide.

I expected to find a pre-rolled library that included joda-time serialisers that I could reference as a Maven dependency - but I can't find one.

Is there one? Or am I forced to replicate that snippet in my own project?

JodaStephen
  • 60,927
  • 15
  • 95
  • 117
Greg Kopff
  • 15,945
  • 12
  • 55
  • 78

6 Answers6

42

I've decided to roll my own open source one - you can find it here:

https://github.com/gkopff/gson-jodatime-serialisers

Here's the Maven details (check central for the latest version):

<dependency>
  <groupId>com.fatboyindustrial.gson-jodatime-serialisers</groupId>
  <artifactId>gson-jodatime-serialisers</artifactId>
  <version>1.6.0</version>
</dependency>

And here's a quick example of how you drive it:

Gson gson = Converters.registerDateTime(new GsonBuilder()).create();
SomeContainerObject original = new SomeContainerObject(new DateTime());

String json = gson.toJson(original);
SomeContainerObject reconstituted = gson.fromJson(json, SomeContainerObject.class);
Boris Treukhov
  • 17,493
  • 9
  • 70
  • 91
Greg Kopff
  • 15,945
  • 12
  • 55
  • 78
  • 4
    There's also one for Java 8's `java.time` classes here: https://github.com/gkopff/gson-javatime-serialisers – Greg Kopff Apr 15 '14 at 00:22
  • @GregKopff thanks for talking with author of official library. Your library is missing `PeriodConverter`. I tried to implement one, but fail. (because I don't understand much, just base on your code). My question here: `http://stackoverflow.com/questions/33219587/gson-jodatime-serialisers-library-implement-periodconverter-for-period-in-joda` Please visit and give me a comment. thanks :) – hqt Oct 20 '15 at 13:43
  • Thanks! I forked it for the "threeten" backport (java.time backport in Java7): https://github.com/pdemanget/gson-threeten-serialisers – pdem Oct 28 '15 at 16:40
  • 1
    Adding it to my Android project gives this error: `Execution failed for task (..) com.android.build.api.transform.TransformException: java.util.zip.ZipException: duplicate entry: org/joda/time/base/AbstractDateTime.class` – RominaV Sep 22 '16 at 15:58
  • 1
    So easy to apply.. Thank you – Odys Oct 21 '16 at 17:40
  • 1
    It works, thank you! For gradle import: `implementation 'com.fatboyindustrial.gson-jodatime-serialisers:gson-jodatime-serialisers:1.7.0'` – fireb86 Oct 10 '18 at 08:51
  • This just saved me an insane amount of time. Thank you so much!! – fudge Sep 12 '21 at 20:24
15

I used the answers above to do a little helper that will handle both serialization and deserialization for model objects containing DateTime variables.

    public static Gson gsonDateTime() {
    Gson gson = new GsonBuilder()
            .registerTypeAdapter(DateTime.class, new JsonSerializer<DateTime>() {
                @Override
                public JsonElement serialize(DateTime json, Type typeOfSrc, JsonSerializationContext context) {
                    return new JsonPrimitive(ISODateTimeFormat.dateTime().print(json));
                }
            })
            .registerTypeAdapter(DateTime.class, new JsonDeserializer<DateTime>() {
                @Override
                public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                    DateTime dt = ISODateTimeFormat.dateTime().parseDateTime(json.getAsString());
                    return dt;
                }
            })
            .create();
    return gson;
}
Tao-Nhan Nguyen
  • 5,508
  • 2
  • 13
  • 9
14

I am using next in my project

public final class DateTimeDeserializer implements JsonDeserializer<DateTime>, JsonSerializer<DateTime>
{
   static final org.joda.time.format.DateTimeFormatter DATE_TIME_FORMATTER =
      ISODateTimeFormat.dateTime().withZone(DateTimeZone.UTC);

   @Override
   public DateTime deserialize(final JsonElement je, final Type type,
                           final JsonDeserializationContext jdc) throws JsonParseException
   {
      return je.getAsString().length() == 0 ? null : DATE_TIME_FORMATTER.parseDateTime(dateAsString);
   }

   @Override
   public JsonElement serialize(final DateTime src, final Type typeOfSrc,
                                final JsonSerializationContext context)
   {
      return new JsonPrimitive(src == null ? StringUtils.EMPTY :DATE_TIME_FORMATTER.print(src)); 
   }
}
Ilya
  • 29,135
  • 19
  • 110
  • 158
  • Hi, can you please provide the imports? I find about 20 Type classes – MartinL May 03 '13 at 20:32
  • @MartinL `GSON` lib is used (https://code.google.com/p/google-gson/). `Type` is class from java-reflection API: `java.lang.reflect.Type` – Ilya May 03 '13 at 21:36
  • i tried to add this to my datetime deserializer, and my app still crashed.... for not being able to read datetime objects what to do ? – Lena Bru Aug 14 '13 at 13:09
  • Didn't work for me either. The date is written correctly viz. [ISO 8601](http://en.wikipedia.org/wiki/ISO_8601), but Gson chokes when it tries to read it back. – Cheezmeister Oct 31 '13 at 02:04
  • @Cheezmeister did you get exception? – Ilya Oct 31 '13 at 06:01
13

register a TypeAdapter with GSON to wrap the use of a Joda preconfigured Formatters, see http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html

import java.lang.reflect.Type;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
import org.joda.time.DateTime;
import org.joda.time.format.ISODateTimeFormat;

public class JodaDateTimeWithGson {

    public static void main(String[] args) {
        Gson gson = new GsonBuilder()
            .registerTypeAdapter(DateTime.class, new JsonSerializer<DateTime>(){
                @Override
                public JsonElement serialize(DateTime json, Type typeOfSrc, JsonSerializationContext context) {
                    return new JsonPrimitive(ISODateTimeFormat.dateTime().print(json));
                }
            })
            .create()
            ;

        // Outputs ["20160222T15:58:33.218Z",42,"String"]
        System.out.println(gson.toJson(new Object[] {DateTime.now(), 42, "String"}));
    }
}
Julien
  • 1,765
  • 20
  • 26
0

It seems to me quite normal that you don't have this kind of library available.

It might look simple at first glance, but the risk is that you end up with a lot of dependencies (some at compile time, some at runtime), and it would not be easy to make sure you don't create unwanted dependencies.

For your case, this should be ok, as I think this is only a runtime dependency (Then a project using the serializerLib should not need JODA lib if JODA is not used). But for some other case, this could become ugly.

Samuel EUSTACHI
  • 3,116
  • 19
  • 24
  • 1
    I would have liked a `gson-jodatime-converter` library that provides GSON serialisers for the various Joda Time entities. That's not going to have run-away dependencies - it just has two: GSON (which I'm already using) and Joda Time (which I'm already using). – Greg Kopff Feb 21 '13 at 11:49
  • I see, then you end up with a lot of dependencies, but with a very modular approach. This would work, but I guess that it does not exist because nobody thought that it would make sense to maintain an open source project for a small bunch of classes – Samuel EUSTACHI Feb 21 '13 at 12:25
  • *I've* decided to maintain that small bunch of classes (and publish the result to Maven Central). See here: http://stackoverflow.com/a/22554290/1212960 – Greg Kopff Mar 30 '14 at 02:12
0

replicate that snippet, a lot of people use different date string formatting thus confusing any library creation.

NimChimpsky
  • 46,453
  • 60
  • 198
  • 311
  • It would be simple for the package to use ISO 8601. It doesn't need to be interoperable with other things (in the first instance) - it just needs to be able to round-trip the data itself. – Greg Kopff Feb 21 '13 at 11:52
  • Yes, this is your need (and mine too) but some projects uses JSON to communicate with heterogeneous environments (for this I try to use SOAP instead, more self documenting with WSDLs), so a lib should need a high level of "configurability" to become standard – Samuel EUSTACHI Feb 21 '13 at 12:23