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

时间:2012-02-03 10:57:11

标签: android .net json parsing datetime

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

我收到的字符串就像:

"DateOfBirth":"\/Date(736032869080)\/"

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

5 个答案:

答案 0 :(得分:11)

像这样:

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..
    }
}

或者使用this example代替&amp;按照“处理WCF Microsoft JSON日期”一章进行操作。

答案 1 :(得分:6)

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

  • “/日期(12345678989 + 0000)/”
  • “/日期(12345678989-0000)/”
  • “/日期(-12345678989 + 0000)/”
  • “/日期(-12345678989-0000)/”

没有TimeZone UTC

  • “/日期(12345678989)/”
  • “/日期(-12345678989)/”

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

1) Google Gson图书馆 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);
    }
}

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反序列化程序

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

转到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());
    }
}

和我的主要/测试类

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

}

我的实用程序/帮助程序类

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

注意: *

  

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

*

答案 2 :(得分:2)

我已经实现了一个GsonHelper,它可以使用GSON从JSON中帮助反序列化序列化 .NET DateTime格式。用法:

// How to get DataClass object from JSON string
Gson gson = new GsonHelper().getGson();
DataClass DATA = gson.fromJson(YOUR_JSON, DataClass.class);

// How to get JSON string from your JSON data
Gson gson = new GsonHelper().getGson();
String JSON = gson.toJson(DATA);

这是助手类:

public class GsonHelper 
{   
    public Gson getGson()
    {
        GsonBuilder builder = new GsonBuilder();
        builder.registerTypeAdapter(Date.class, new DotNetDateDeserializer());
        builder.registerTypeAdapter(Date.class, new DotNetDateSerializer());
        return builder.create();
    }

    public class DotNetDateDeserializer implements JsonDeserializer<Date> 
    {
        @Override
        public Date deserialize(JsonElement json, Type typfOfT, JsonDeserializationContext context)
        {
            try
            {
                String dateStr = json.getAsString();
                if (dateStr != null) dateStr = dateStr.replace("/Date(", "");
                if (dateStr != null) dateStr = dateStr.replace("+0000)/", "");
                if (dateStr != null) dateStr = dateStr.replace(")/", "");
                long time = Long.parseLong(dateStr);
                return new Date(time);
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
                return null;
            }

        }
    }

    public class DotNetDateSerializer implements JsonSerializer<Date> 
    {
        @Override
        public JsonElement serialize(Date date, Type typfOfT, JsonSerializationContext context)
        {
            if (date == null)
                return null;

            String dateStr = "/Date(" + date.getTime() + ")/";
            return new JsonPrimitive(dateStr);
        }
    }

注意:适用于两种格式:/Date(1362853251000)//Date(1362853251000+0000)/。必须根据时间定义辅助器以适应其他格式。

答案 3 :(得分:2)

要手动将.NET JSON日期转换为JodaTime DateTime对象(类似的本机Java类型),您还可以使用正则表达式:

public static DateTime parseDotNetTime(String json) {
    DateTime result = null;
    if (json != null) {
        Pattern datePatt = Pattern.compile("^/Date\\((\\d+)([+-]\\d+)?\\)/$");
        Matcher m = datePatt.matcher(json);
        if (m.matches()) {
            Long l = Long.parseLong(m.group(1));
            result = new DateTime(l);
            // Time zone is not needed to calculate date
        } else {
            throw new IllegalArgumentException("Wrong date format");
        }
    }
    return result;
}

答案 4 :(得分:-1)

不知道......我曾经尝试过以上所有......但是对我来说不起作用。最后我来了这个解决方案:)

当你从json对象字符串中获取字符串时会得到:“/ Date(1373543393598 + 0200)/”。但是如果您将看到从服务器传入的结果字符串将如下所示:{“respDateTime”:“/ Date(1373267484478 + 0200)/”}

String json = "/Date(1373543393598+0200)/"; 
json=json.replace("/Date(", "").replace("+0200)/", "");
long time = Long.parseLong(json);
Date d= new Date(time);