如何将.net DateTime作为json字符串解析为java的Date对象

waq*_*lam 5 .net datetime parsing android json

DateTime通过我的asmx webservice 接收.NET的对象作为json字符串,并尝试在gson库的帮助下解析它.但似乎没有支持解析.net样式的DateTime.如何Date使用Gson 轻松地将其解析为java的对象而没有太多麻烦?

我收到的字符串如下:

"DateOfBirth":"\/Date(736032869080)\/"
Run Code Online (Sandbox Code Playgroud)

PS我不想在服务器端进行任何修改以将DateTime作为Long值接收

Jen*_*ens 12

像这样:

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..
    }
}
Run Code Online (Sandbox Code Playgroud)

或者使用此示例,并按照"处理WCF Microsoft JSON日期"一章进行操作.


Jom*_*oma 7

我实现了这个,可以与.NET WCF DateTime Json格式互操作.随着时区

  • "/日期(12345678989 + 0000)/"
  • "/日期(12345678989-0000)/"
  • "/日期(-12345678989 + 0000)/"
  • "/日期(-12345678989-0000)/"

没有TimeZone UTC

  • "/日期(12345678989)/"
  • "/日期(-12345678989)/"

首先,您需要添加到您的项目

1)Google Gson Library GSON

2)JodaTime库 JodaTime 在JDK8之前使用.

在JDK8或更高版本上使用java.time.

主要课程

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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()));
        }
    }
Run Code Online (Sandbox Code Playgroud)

DateTime反序列化器

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

转到Regex101.测试这个正则表达式

要序列化的示例类

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

和我的主要/测试课程

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));
    }

}
Run Code Online (Sandbox Code Playgroud)

我的Util/Helper类

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

注意: *

序列化/反序列化时的所有DateTime值都将转换为UTC.

*