Menu

json conversion to java.util.Date

Help
2007-11-05
2013-04-29
  • Jochen Frank

    Jochen Frank - 2007-11-05

    I want to convert the birthday in
    {..., "birthday":{"day":5,"month":11,"year":2007}}
    to a java.util.Date object.

    In Java I would do it like this:
    setBirthday( new GregorianCalendar( year, month-1, day ).getTime() )

    How do I have to configure json-lib,
    that it converts automatically with
    JSONObject.toBean(...)?

     
    • aalmiray

      aalmiray - 2007-11-05

      Hi Jochen,

      You'll need to register a Morpher (from EZMorph) to handle this case. EZMorpher includes a DateMorpher that takes a date literal and transforms it into a java.util.Date but in your case you need to transform a "bean" into a java.util.Date

      Cheers,
      Andres

       
    • Jochen Frank

      Jochen Frank - 2007-11-06

      Could you please help.
      I have the following classes:

      public class TestBean {
          java.util.Date value;
          // +Getter&Setter for value
      }

      public class MyDateMorpher {
          public Class morphsTo() { return java.util.Date; }
          public boolean supports(Class clazz) { // Not called }
          public Object morph(Object value) { // Not called }
      }

      main() {
          String jsonString = "{\"value\":{\"day\":1,\"month\":2,\"year\":1980}}";
          JSONUtils.getMorpherRegistry().registerMorpher(new MyDateMorpher());
          JSONObject jsonObject = JSONObject.fromObject(jsonString);
          TestBean testBean = (TestBean)JSONObject.toBean(jsonObject, TestBean.class);
      }

      Results in:
      net.sf.json.JSONObject toBean
      WARNING: Property 'day' has no write method. SKIPPED.

      The Morpher isn't called.

       
    • aalmiray

      aalmiray - 2007-11-06

      I think there may be a bug in EZMorph if several morphers for the same target class are registered
      MorpherRegistry.morph will call the first available morpher, in your case I think a DateMorpher is already registered but it only supports String.class
      Please try by deregistering any morpher for Date before calling your code again. I'll update EZMoprh anyway.

       
      • Jochen Frank

        Jochen Frank - 2007-11-06

        The morpher I get for java.util.Date is the IdentityObjectMorpher. I can't remove this one.

         
    • aalmiray

      aalmiray - 2007-11-06

      Hmm I thought it should return a DateMorpher with default date formats. In any case I can confirm there is a bug in EZMorph and it has been fixed yesterday. I'll release it soon and then update json-lib-2.2-SNAPSHOT with the fix.

      Cheers,
      Andres

       
      • Jochen Frank

        Jochen Frank - 2007-11-06

        I tried it with the ezmorph from the cvs repository.
        There isn't even a search for a Morpher in json-lib for my example.

         
    • aalmiray

      aalmiray - 2007-11-06

      Well that's surprising, I'll give it a look tonight and see what's happening. There is a chance a BeanMorpher is being registered automatically but if your Morpher is already in place the code should pick it up. Out of curiosity, what's the impl of your 'supports(Class clazz)' ? it should support JSONObject at least.

       
    • aalmiray

      aalmiray - 2007-11-07

      I ran the following test against ezmorph-1.0.4 and it works ok, you should download a copy from ezmorph's cvs and build your own as I have not released yet. No changes to json-lib are needed.

         public void testToBeanWithMultipleMorphersForTargetType() {
            Calendar c = Calendar.getInstance();
            c.set( Calendar.YEAR, 2007 );
            c.set( Calendar.MONTH, 5 );
            c.set( Calendar.DAY_OF_MONTH, 17 );
            c.set( Calendar.HOUR_OF_DAY, 12 );
            c.set( Calendar.MINUTE, 13 );
            c.set( Calendar.SECOND, 14 );
            c.set( Calendar.MILLISECOND, 150 );
            Date date = c.getTime();

            DateBean bean = new DateBean();
            bean.setDate( date );
            JSONObject jsonObject = JSONObject.fromObject( bean );

            JSONUtils.getMorpherRegistry()
                  .registerMorpher( new MapToDateMorpher() );

            JsonConfig jsonConfig = new JsonConfig();
            jsonConfig.setRootClass( DateBean.class );
            DateBean actual = (DateBean) JSONObject.toBean( jsonObject, jsonConfig );
            Calendar d = Calendar.getInstance();
            d.setTime( actual.getDate() );
            assertEquals( c.get( Calendar.YEAR ), d.get( Calendar.YEAR ) );
            assertEquals( c.get( Calendar.MONTH ), d.get( Calendar.MONTH ) );
            assertEquals( c.get( Calendar.DATE ), d.get( Calendar.DATE ) );
            assertEquals( c.get( Calendar.HOUR_OF_DAY ), d.get( Calendar.HOUR_OF_DAY ) );
            assertEquals( c.get( Calendar.MINUTE ), d.get( Calendar.MINUTE ) );
            assertEquals( c.get( Calendar.SECOND ), d.get( Calendar.SECOND ) );
            assertEquals( c.get( Calendar.MILLISECOND ), d.get( Calendar.MILLISECOND ) );
         }

      public class MapToDateMorpher extends AbstractObjectMorpher {
         public Object morph( Object value ) {
            if( value == null || !(value instanceof Map) ){
               return null;
            }
            Map map = (Map) value;
            Calendar c = Calendar.getInstance();
            c.set( Calendar.YEAR, getValue( map, "year" ) );
            c.set( Calendar.MONTH, getValue( map, "month" ) );
            c.set( Calendar.DATE, getValue( map, "day" ) );
            c.set( Calendar.HOUR_OF_DAY, getValue( map, "hour" ) );
            c.set( Calendar.MINUTE, getValue( map, "minutes" ) );
            c.set( Calendar.SECOND, getValue( map, "seconds" ) );
            c.set( Calendar.MILLISECOND, getValue( map, "milliseconds" ) );
            return c.getTime();
         }

         public Class morphsTo() {
            return Date.class;
         }

         public boolean supports( Class clazz ) {
            return clazz != null && Map.class.isAssignableFrom( clazz );
         }

         private int getValue( Map map, String key ) {
            Object value = map.get( key );
            if( value == null || !(value instanceof Number) ){
               return 0;
            }

            Number n = (Number) value;
            return n.intValue();
         }
      }

       
    • Jochen Frank

      Jochen Frank - 2007-11-07

      I testet it with ezmorph-1.0.4. The Morpher isn't called.

      Look at the 'day' in the JSON string: {"month":5,"day":0,"year":107,...} It is 0.

       
    • aalmiray

      aalmiray - 2007-11-07

      Actually if you are transforming back to JSON what you got from the morphed bean then it seems to me the datemorpher was called as year is 107 and day is 0. Could you please send me your testing code? I did some changes after sending the previous message and want to find out if there is a still a bug lurking somewhere, thanks.

       
    • Jochen Frank

      Jochen Frank - 2007-11-08

      I'm doing this:

      main() {
      String jsonString = "{\"date\":{\"day\":15,\"month\":5,\"year\":1977}}";
      JSONObject json = JSONObject.fromObject(jsonString);
      JSONUtils.getMorpherRegistry().registerMorpher( new MapToDateMorpher() );
      TestBean actual = (TestBean) JSONObject.toBean( json, TestBean.class );
      }

      public class MapToDateMorpher extends AbstractObjectMorpher {
      public Class morphsTo() { return Date.class; }
      public Object morph( Object value ) { System.out.println("MORPH CALLED"); }
      public boolean supports( Class clazz ) { System.out.println("SUPPORTS CALLED"); }
      }

      public class TestBean {
      Date date;
      // Getter,Setter
      }

      I get the WARNING: Property 'day' has no write method. SKIPPED.
      The methods morph and supports are NOT called.

       
      • aalmiray

        aalmiray - 2007-11-08

        You did noticed that I used another version of toBean, the one that accepts JsonConfig as the second parameter. But the code you show should work, perhaps this is a regression on the previous way of calling that method. I'll look further into it.

         

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.