Как разобрать .net DateTime, полученный в виде строки json, в объект Date Java - PullRequest
4 голосов
/ 03 февраля 2012

Я получаю объект .NET DateTime в виде строки json через мой веб-сервис asmx и пытаюсь проанализировать его с помощью библиотеки gson. Но похоже, что нет поддержки для разбора .net в стиле DateTime. Как я могу легко разобрать его в Date объект Java, используя Gson без особых хлопот?

полученная строка выглядит так:

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

P.S. Я не хотел бы вносить какие-либо изменения на стороне сервера, чтобы получить DateTime в качестве значения Long

Ответы [ 5 ]

11 голосов
/ 03 февраля 2012

Как это:

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

Или используйте этот пример вместо этого и следуйте главе "Работа с WCF Microsoft JSON Dates".

7 голосов
/ 19 июня 2015

Я реализовал это, совместимо с форматом .NET WCF DateTime Json.С часовым поясом

  • "/ Дата (12345678989 + 0000) /"
  • "/ Дата (12345678989-0000) /"
  • "/ Дата (-12345678989+0000) / "
  • " / Дата (-12345678989-0000) / "

Без часового пояса 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);
    }
}

Сериализатор DateTime

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

}

MyКласс 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;
    }
}

Примечание: *

Все значения DateTime при сериализации / десериализации преобразуются в UTC.

*

2 голосов
/ 13 мая 2014

Чтобы вручную преобразовать дату .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;
}
2 голосов
/ 10 марта 2013

Я реализовал GsonHelper, который помогает десериализацию и сериализации .NET DateTime формата из JSON с использованием GSON. Использование:

// 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)/. Помощник должен быть настроен на другие форматы с определенным временем.

0 голосов
/ 11 июля 2013

Не знаю ... Я пробовал все выше ... но у меня не получилось.наконец, я пришел с этим решением :)

когда вы получите строку из объекта 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); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...