简体   繁体   English

日期的无效 json 表示

[英]Invalid json representation of date

My code:我的代码:

import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
...
public void testDateSerializer() {
  final Date date = new Date();
  log.info("Today's date: " + date + " and date.getTime()=" + date.getTime());
  final JSONObject jsonObjectForDate = (JSONObject) JSONSerializer.toJSON(date);
  log.info("Same date expressed in json: " + jsonObjectForDate.toString());
}

The output: output:

INFO - 2011-08-13 22:12:04,938 - TestJsonConversion.testDateSerializer(52) | Today's date: Sat Aug 13 22:12:04 EDT 2011 and date.getTime()=1313287924927
INFO - 2011-08-13 22:12:05,216 - TestJsonConversion.testDateSerializer(55) | Same date expressed in json: {"date":13,"day":6,"hours":22,"minutes":12,"month":7,"seconds":4,"time":1313287924927,"timezoneOffset":240,"year":111}

My questions:我的问题:

  • Why year=111.为什么年份=111。 We are still in 2011 unless I missed something!除非我错过了什么,否则我们仍处于 2011 年!
  • I am on US ETD, so offset is -4 hours, not +240, which, even expressed in minutes is still wrong regarding the sign of the offset.我在美国 ETD,所以偏移量是 -4 小时,而不是 +240,即使以分钟表示,关于偏移量的符号仍然是错误的。

So what am I doing wrong?那么我做错了什么? Is this a bug in the library?这是库中的错误吗? If so, what library should I use to accomplish the same conversion?如果是这样,我应该使用什么库来完成相同的转换?

Thank you谢谢

Joda Time is indeed the way to go. Joda Time 确实是通往 go 的方式。 However, if you are stuck with java.util.Date for whatever reason, you could customize the serialization this way:但是,如果您因任何原因被java.util.Date卡住,您可以通过以下方式自定义序列化:

   JsonConfig config = new JsonConfig();
   config.registerJsonValueProcessor(
        Class.forName("java.util.Date"), 
        new NiceDateJsonBeanProcessor());
   final JSONObject jsonObjectForDate = JSONSerializer.toJSON(object, jsonConfig)

Where NiceDateJsonBeanProcessor is how you define what you want your java.util.Date object to be serialized as. NiceDateJsonBeanProcessor是您定义您希望java.util.Date object 序列化为的方式。 In my case, I was happy with unix time, so:就我而言,我对 unix 时间感到满意,所以:

public static class NiceDateJsonBeanProcessor implements JsonValueProcessor {
    @Override
    public Object processArrayValue(Object value, JsonConfig jsonConfig) {
        return process(value, jsonConfig);
    }
    @Override
    public Object processObjectValue(String key, Object value, JsonConfig jsonConfig) {
        return process(value, jsonConfig);
    }
    private Object process(Object value, JsonConfig jsonConfig) {
        if (value instanceof java.util.Date) {
            java.util.Date d = (java.util.Date) value;
            return d.getTime();
        }
        return null;
    }
}

Actually this behavior is completely expected, believe it or not.其实这种行为完全是意料之中的,信不信由你。

You are using the class java.util.Date .您正在使用 class java.util.Date This class has mostly a bunch of deprecated methods.这个 class 主要有一堆不推荐使用的方法。 See the documentation here:请参阅此处的文档:

http://download.oracle.com/javase/6/docs/api/java/util/Date.html http://download.oracle.com/javase/6/docs/api/java/util/Date.html

Now your JSON serializer is just going to make a JSON string out of the getters in your Java object.现在您的 JSON 序列化器将在您的 Java2666CFDE63931BDC49. Take a look at the getters in the java.util.Date class.看看java.util.Date class 中的吸气剂。 Most are deprecated and you can see why.大多数已被弃用,您可以看到原因。 The year is relative to 1900!年份是相对于 1900 年的! The time zone offset is in minutes backwards.时区偏移以分钟单位倒退。

To make your application work the way you would expect, check out the deprecation warnings for Date which tell you to use GregorianCalendar .要使您的应用程序按您期望的方式工作,请查看Date的弃用警告,它告诉您使用GregorianCalendar However, I recommend using JodaTime .但是,我建议使用JodaTime A little learning curve, but this is so worth it.有点学习曲线,但这是非常值得的。

It might help to look at the source of JSONObject here这里查看 JSONObject 的来源可能会有所帮助

Basically, it treats your passed-in Date object as a Java Bean.基本上,它将您传入的日期 object 视为 Java Bean。 So, it iterates through reflection, all the "get*" methods in your date object and that's what you see in your JSONObject.因此,它通过反射进行迭代,您的日期 object 中的所有“get*”方法,这就是您在 JSONObject 中看到的内容。

All the java.util.Date object's get methods are deprecated and you see weirdness, like the year being 111 instead of 2011.所有java.util.Date对象的 get 方法都已弃用,您会看到奇怪的现象,例如年份是 111 而不是 2011。

If you want to pass date objects via JSON, you might consider passing them as String objects formatted in a specific way OR use Calendar.如果您想通过 JSON 传递日期对象,您可以考虑将它们作为以特定方式格式化的字符串对象或使用日历传递。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM