3

I am using ServiceStack 4.5.6 with Visual Studio 2015. In my current situation, I am using SS just as client. The REST server is written in Java by a third party company. I wrote the Model classes, DTOs, etc. to match the routes of the server.

But now I have the following problems: Exchanging Integers or Strings is no problem. But It seems to be really difficult to exchange DateTime values.

Java seems to use different DateTime format strings than C# / ServiceStack, and I can not find a common one right now.

Here are some examples I got from the developer of the server:

Java:

2012-06-30T12:30:40+01:00
2012-06-30T12:30:40Z 
2012-06-30T12:30:40Z[GMT]
2012-06-30T12:30:40Z[UT]
2012-06-30T12:30:40Z[UTC]
2016-11-05 13:45
2016-05-15 20:15:23.340

So in most of the cases, Java adds a Z or a [Timezone]. I was not able, to produce any of these formats exactly with ServiceStack.

E.g. with the following code:

                using (var scope = JsConfig.BeginScope())
                {
                    scope.DateHandler = DateHandler.ISO8601;
                    return client.Post(request);
                }

I get this result

2018-04-09T17:14:19.1201876+02:00

which almost looks like the first java example - but the nanoseconds are too much.

I know, I can use a custom format, as described here: ServiceStack - Is there a way to force all serialized Dates to use a specific DateTimeKind? Is it possible, to use such a custom format only for a specific JsonServiceClient? I am not able to use it global for my whole application.

Best regards, Daniel

Daniel P.
  • 43
  • 4

2 Answers2

2

ISO 8601

I cannot tell you the exact details, but I should say that your best bet is ISO 8601 format, the international standard. Your example strings follow this standard or come close, so I hope it will be viable.

Java: Your first two examples, 2012-06-30T12:30:40+01:00 and 2012-06-30T12:30:40Z, are ISO 8601. The Z is a common way to denote offset 0, it shouldn’t pose any problem anywhere. The square brackets with time zones in the next examples are Java specific, other than that they comply with ISO too. If you receive such strings, you will have to strip off the brackets or just parse the strings as far as it goes and ignore any unparsed chars. The strings that lack the T between date and time do not comply as far as I know.

ServiceStack: 2018-04-09T17:14:19.1201876+02:00 is exactly ISO 8601. Java should have no problems accepting this format. The number of decimals is free (and they are optional, they are allowed to be present or not).

OffsetDateTime odt = OffsetDateTime.parse( "2018-04-09T17:14:19.1201876+02:00" ) ;

I don’t know ServiceStack and I obviously don’t know that particula Java server, so this is as close as I can get.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • Furthermore, I suggest simply deleting any occurrence of `[GMT]`, `[UT]`, and `[UTC]` after the `Z`, then process as shown in the Answer. For the last two examples in the Question with neither zone nor offset, replace the SPACE in the middle with a `T` and parse as a [`LocalDateTime`](https://docs.oracle.com/javase/10/docs/api/java/time/LocalDateTime.html) lacking any concept of time zone or [offset-from-UTC](https://en.wikipedia.org/wiki/UTC_offset): `LocalDateTime.parse( "2016-11-05 13:45".replace( " " , "T" ) )` – Basil Bourque Apr 09 '18 at 22:51
  • You are right, thank you. I will use the ISO8601 format now, e.g. `2018-04-09T17:14:19.1201876+02:00` I thought that Java wouldn't understand this format, as there is a decimal part, which is not included in the examples. But after speaking with the developer of our server, this doesn't seem to be a problem. – Daniel P. Apr 12 '18 at 09:26
0

There's no way to force different responses for specific ServiceClients.

If you need to change the DateTime implementation in Java you can replace the existing DateTime impl with your own by customizing the Date serializer used by Gson serializer, e.g:

JsonServiceClient client = new JsonServiceClient(baseUrl);
GsonBuilder gsonBuilder = client.getGsonBuilder();
gsonBuilder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
        @Override
        public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            return json == null ? null : Utils.parseDate(json.getAsString());
        }
    });
client.setGson(gsonBuilder.disableHtmlEscaping().create());

Otherwise the alternative way to ensure an exact formatted date is to serialize it as a string in C# and have your DTOs return a string.

mythz
  • 141,670
  • 29
  • 246
  • 390
  • The server side does not use ServiceStack, so this won't help. But I will go with DateHandler.ISO8601 now. I think I found my mistake: For testing I used the REST client Postman. There I forgot to encode the + sign, so I got weird results. – Daniel P. Apr 12 '18 at 09:27