How to parse .net DateTime received as json string into java's Date object

后端 未结 5 2173
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-09 22:57

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 su

相关标签:
5条回答
  • 2020-12-09 23:33

    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.

    0 讨论(0)
  • 2020-12-09 23:39

    To manually convert a .NET JSON date to a JodaTime DateTime object (native Java type similar), you can also use a regex:

    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;
    }
    
    0 讨论(0)
  • 2020-12-09 23:44

    Dont Know...I had tryed all above.. but didn't work for me. finally I have come with this solution :)

    when you get string from json object string will get like : "/Date(1373543393598+0200)/". but if You will see on result string which is comming from server will look like this: {"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); 
    
    0 讨论(0)
  • 2020-12-09 23:55

    I've implemented this, interoperable with .NET WCF DateTime Json format. With Time Zone

    • "/Date(12345678989+0000)/"
    • "/Date(12345678989-0000)/"
    • "/Date(-12345678989+0000)/"
    • "/Date(-12345678989-0000)/"

    Without TimeZone UTC

    • "/Date(12345678989)/"
    • "/Date(-12345678989)/"

    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.

    *

    0 讨论(0)
  • 2020-12-09 23:55

    I've implemented a GsonHelper, which helps deserializing and serializing .NET DateTime format from JSON using GSON. Usage:

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

    This is the helper class:

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

    Note: works for two formats: /Date(1362853251000)/ and /Date(1362853251000+0000)/. Helper have to be tuned for other formats with time defined.

    0 讨论(0)
提交回复
热议问题