I'm receiving .NET's DateTime
object as json string through my asmx webservice and trying to parse it with help of gson library. But seems like there's no support to parse .net style DateTime.
How can i parse it easily into java's Date
object using Gson without much hassle?
the string i receive is like:
"DateOfBirth":"\/Date(736032869080)\/"
P.S. I would not like to make any modifications at server side to receive DateTime as a Long value
Json library parses and writes DateTime and DateTimeOffset values according to the ISO 8601-1:2019 extended profile.
To represent dates in JavaScript, JSON uses ISO 8601 string format to encode dates as a string. Dates are encoded as ISO 8601 strings and then treated just like a regular string when the JSON is serialized and deserialized.
JSON does not have a built-in type for date/time values. The general consensus is to store the date/time value as a string in ISO 8601 format.
JSON does not directly support the date format and it stores it as String. However, as you have learned by now that mongo shell is a JavaScript interpreter and so in order to represent dates in JavaScript, JSON uses a specific string format ISODate to encode dates as string.
Like this:
String json = "\"\\/Date(736032869080)\\/\"";
Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new NetDateTimeAdapter()).create();
System.out.println("Date=" + gson.fromJson(json, Date.class));
class NetDateTimeAdapter extends TypeAdapter<Date> {
@Override
public Date read(JsonReader reader) throws IOException {
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
return null;
}
Date result = null;
String str = reader.nextString();
str = str.replaceAll("[^0-9]", "");
if (!TextUtils.isEmpty(str)) {
try {
result = new Date(Long.parseLong(str));
} catch (NumberFormatException e) {
}
}
return result;
}
@Override
public void write(JsonWriter writer, Date value) throws IOException {
// Nah..
}
}
Or use this example instead & follow the "Dealing with WCF Microsoft JSON Dates" chapter.
I've implemented this, interoperable with .NET WCF DateTime Json format. With Time Zone
Without TimeZone UTC
First you need add to your project
1) Google Gson Library GSON
2) JodaTime library JodaTime Use prior to JDK8.
On JDK8 or above use java.time instead.
Main class
package tests;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.joda.time.DateTime;
/**
*
* @author Joma Espinoza Bone.
*/
public class JsonSerializerDeserializer {
private static Gson handler = null;
public static void initialize(Boolean useDotNetFormat) {
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(DateTime.class, new DateTimeSerializer(useDotNetFormat));
builder.registerTypeAdapter(DateTime.class, new DateTimeDeserializer(useDotNetFormat));
handler = builder.create();
}
private JsonSerializerDeserializer() {
}
public static <T> String serialize(T instance, Boolean useDotNetFormat) {
initialize(useDotNetFormat);
if (useDotNetFormat) {
return (handler.toJson(instance, instance.getClass())).replace("/", "\\/");
} else {
return handler.toJson(instance, instance.getClass());
}
}
public static <T> T deserialize(String json, Class<T> resultType) {
initialize(json.contains("\\/Date("));
return handler.fromJson(json, resultType);
}
}
DateTime Serializer
package tests;
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.DateTimeZone;
import org.joda.time.format.ISODateTimeFormat;
/**
*
* @author Joma Espinoza Bone.
*/
public class DateTimeSerializer implements JsonSerializer<DateTime> {
private Boolean toDotNetFormat;
private DateTimeSerializer() {
}
public DateTimeSerializer(Boolean isInDotNetFormat) {
this.toDotNetFormat = isInDotNetFormat;
}
@Override
public JsonElement serialize(DateTime t, Type type, JsonSerializationContext jsc) {
if (t.getZone() != DateTimeZone.UTC) {
int offset = t.getZone().getOffsetFromLocal(t.getMillis());
t = t.toDateTime(DateTimeZone.UTC).plus(offset);
}
return toDotNetFormat ? new JsonPrimitive(Strings.format("/Date({0})/", t.getMillis())) : new JsonPrimitive(t.toString(ISODateTimeFormat.dateTime()));
}
}
DateTime Deserializer
package tests;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import java.lang.reflect.Type;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
/**
*
* @author Joma Espinoza Bone.
*/
public class DateTimeDeserializer implements JsonDeserializer<DateTime> {
Boolean isInDotNetFormat;
private DateTimeDeserializer() {
}
public DateTimeDeserializer(Boolean isInDotNetFormat) {
this();
this.isInDotNetFormat = isInDotNetFormat;
}
@Override
public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
String jsonString = json.getAsJsonPrimitive().getAsString();
if (isInDotNetFormat) {
String Regexp = "\\/Date\\((\\-?\\d*?)([\\+\\-]\\d*)?\\)\\/";
Pattern MyPattern = Pattern.compile(Regexp);
Matcher MyMatcher = MyPattern.matcher(jsonString);
MyMatcher.matches();
Long time = new Long(MyMatcher.group(1));
if (Strings.isNullOrWhiteSpace(MyMatcher.group(2))) {
return new DateTime(time, DateTimeZone.UTC);
} else {
Integer offsetHours = Integer.parseInt(MyMatcher.group(2).substring(0, 3));
Integer offsetMinutes = Integer.parseInt(MyMatcher.group(2).substring(3, MyMatcher.group(2).length()));
int offset = DateTimeZone.forOffsetHoursMinutes(offsetHours, offsetMinutes).getOffsetFromLocal(time);
return new DateTime(time + offset).toDateTime(DateTimeZone.UTC);
}
} else {
DateTime t = DateTime.parse(jsonString.substring(0, jsonString.length()));
if (t.getZone() != DateTimeZone.UTC) {
int offset = t.getZone().getOffsetFromLocal(t.getMillis());
t = t.toDateTime(DateTimeZone.UTC).plus(offset);
}
return t;
}
}
}
Go to Regex101. Test this regexp
Sample class to Serialize
package tests;
import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.format.ISODateTimeFormat;
/**
*
* @author Joma Espinoza Bone.
*/
public class MyClass {
private DateTime DateTime;
private String Names;
public DateTime getDateTime() {
return DateTime;
}
public void setDateTime(DateTime DateTime) {
this.DateTime = DateTime;
}
public String getNames() {
return Names;
}
public void setNames(String Names) {
this.Names = Names;
}
@Override
public String toString() {
return "Names: " + Names + " // DateTime: " + DateTime.toString(ISODateTimeFormat.dateTime());
}
}
and my main/test class
package tests;
import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.format.ISODateTimeFormat;
/**
*
* @author Joma Espinoza Bone.
*/
public class Tests {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
DateTime dateTime = new DateTime();//new DateTime(1467880743533L, DateTimeZone.forOffsetHours(-5));
System.out.println(dateTime.toString(ISODateTimeFormat.dateTime()));
String json = JsonSerializerDeserializer.serialize(dateTime, Boolean.TRUE);
System.out.println(json);
dateTime = JsonSerializerDeserializer.deserialize(json, DateTime.class);
System.out.println(dateTime.toString(ISODateTimeFormat.dateTime()));
MyClass obj = new MyClass();
DateTime datetime = new DateTime(new Date(115, 5, 18, 18, 5, 14));//new Date(Calendar.getInstance().getTimeInMillis());
obj.setDateTime(datetime);
obj.setNames("Joma");
String jsonDotNet = JsonSerializerDeserializer.serialize(obj, true);
String jsonJava = JsonSerializerDeserializer.serialize(obj, Boolean.FALSE);
System.out.println("Json DotNet: " + jsonDotNet);
System.out.println("Json Java: " + jsonJava);
System.out.println("Deserialized DotNet: " + JsonSerializerDeserializer.deserialize(jsonDotNet, MyClass.class).toString());
System.out.println("Deserialized Java: " + JsonSerializerDeserializer.deserialize(jsonJava, MyClass.class).toString());
//18/06/2015 21:35:45 Generated from DotNet Date with TimeZone.
String json1 = "{\"DateTime\":\"\\/Date(1434681345267-0500)\\/\",\"Names\":\"Joma\"}";
//18/06/2015 21:35:45 Generated from JsonSerializerDeserializer.serialize(Object instance, Boolean ToDotNetFormat) DotNetFormat without TimeZone.
String json2 = "{\"DateTime\":\"\\/Date(1434663345267)\\/\",\"Names\":\"Joma\"}";
// Java DateTime with TimeZone.
String json3 = "{\"DateTime\":\"2016-07-07T16:40:27.720-05:00\",\"Names\":\"Joma\"}";
//Java DateTime without TimeZone - UTC
String json4 = "{\"DateTime\":\"2016-07-07T16:40:27.720Z\",\"Names\":\"Joma\"}";
System.out.println("Deserialized 1: " + JsonSerializerDeserializer.deserialize(json1, MyClass.class));
System.out.println("Deserialized 2: " + JsonSerializerDeserializer.deserialize(json2, MyClass.class));
System.out.println("Deserialized 3: " + JsonSerializerDeserializer.deserialize(json3, MyClass.class));
System.out.println("Deserialized 4: " + JsonSerializerDeserializer.deserialize(json4, MyClass.class));
}
}
My Util/Helper Class
package tests;
/**
* Created by Joma on 17/06/2015.
*/
public class Strings
{
public static Boolean isNullOrEmpty(String value)
{
if (value != null)
{
return value.length() == 0;
}
else
{
return true;
}
}
public static Boolean isNullOrWhiteSpace(String value)
{
if (value == null)
{
return true;
}
if (value.trim().length() == 0)
{
return true;
}
else
{
return false;
}
}
public static String format(String format, Object... params)
{
for(int i = 0; i< params.length; i++)
{
format = format.replaceAll(String.format("\\{%s\\}", i), params[i].toString());
}
return format;
}
}
Note: *
All DateTime values when serialized/deserialized are converted to UTC.
*
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With