我通过我的asmx webservice接收.NET的DateTime
对象作为json字符串,并尝试在gson库的帮助下解析它。但似乎没有支持解析.net样式的DateTime。
如何使用Gson轻松地将其解析为java的Date
对象而没有太多麻烦?
我收到的字符串就像:
"DateOfBirth":"\/Date(736032869080)\/"
P.S。我不想在服务器端进行任何修改以将DateTime作为Long值接收
答案 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格式互操作。 带时区
没有TimeZone UTC
首先,您需要添加到项目中
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);