Hi.This patch creates a _dump-method for Time that matches what Ruby 1.8 creates. The code is created by looking at time.c in the Ruby distro. I have also added some methods to support marshal_dump later on. What's missing is a correct implementation of _load in Time, but that will come soon too.
Regards Ola Bini
Index: src/org/jruby/RubyTime.java =================================================================== RCS file: /cvsroot/jruby/jruby/src/org/jruby/RubyTime.java,v retrieving revision 1.18 diff -u -r1.18 RubyTime.java --- src/org/jruby/RubyTime.java 26 Mar 2006 21:21:40 -0000 1.18 +++ src/org/jruby/RubyTime.java 31 Mar 2006 12:45:46 -0000 @@ -269,4 +269,38 @@ // modified to match how hash is calculated in 1.8.2 return getRuntime().newFixnum((int)(((cal.getTimeInMillis() / 1000) ^ microseconds()) << 1) >> 1); } + + public RubyString dump(final IRubyObject[] args) { + if (args.length > 1) { + throw getRuntime().newArgumentError(0, 1); + } + final RubyFixnum limit = (args.length == 0)?RubyFixnum.minus_one(getRuntime()):(RubyFixnum)args[0]; + return (RubyString)mdump(new IRubyObject[] {this}); + } + + public RubyObject mdump(final IRubyObject[] args) { + final RubyTime obj = (RubyTime)args[0]; + final Calendar cel = obj.gmtime().cal; + final byte buf[] = new byte[8]; + int pe = + 0x1 << 31 | + (cel.get(Calendar.YEAR)-1900) << 14 | + cel.get(Calendar.MONTH) << 10 | + cel.get(Calendar.DAY_OF_MONTH) << 5 | + cel.get(Calendar.HOUR_OF_DAY); + + int se = + cel.get(Calendar.MINUTE) << 26 | + cel.get(Calendar.SECOND) << 20 | + cel.get(Calendar.MILLISECOND); + for(int i=0;i<4;i++) { + buf[i] = (byte)(pe & 0xFF); + pe >>= 8; + } + for(int i=4;i<8;i++) { + buf[i] = (byte)(se & 0xFF); + se >>= 8; + } + return RubyString.newString(obj.getRuntime(),buf); + } } Index: src/org/jruby/runtime/marshal/MarshalStream.java =================================================================== RCS file: /cvsroot/jruby/jruby/src/org/jruby/runtime/marshal/MarshalStream.java,v retrieving revision 1.13 diff -u -r1.13 MarshalStream.java --- src/org/jruby/runtime/marshal/MarshalStream.java 26 Oct 2005 05:34:13 -0000 1.13 +++ src/org/jruby/runtime/marshal/MarshalStream.java 31 Mar 2006 10:21:42 -0000 @@ -54,6 +54,10 @@ private int depth = 0; private MarshalCache cache; + private final static char TYPE_USRMARSHAL = 'U'; + private final static char TYPE_USERDEF = 'u'; + + public MarshalStream(IRuby runtime, OutputStream out, int depthLimit) throws IOException { super(out); @@ -72,6 +76,8 @@ } if (! shouldBeRegistered(value)) { writeDirectly(value); + } else if (hasNewUserDefinedMarshaling(value)) { + userNewMarshal(value); } else if (hasUserDefinedMarshaling(value)) { userMarshal(value); } else { @@ -115,14 +121,22 @@ return value.respondsTo("_dump"); } + private boolean hasNewUserDefinedMarshaling(IRubyObject value) { + return value.respondsTo("marshal_dump"); + } + private void userMarshal(IRubyObject value) throws IOException { - out.write('u'); + out.write(TYPE_USERDEF); dumpObject(RubySymbol.newSymbol(runtime, value.getMetaClass().getName())); RubyString marshaled = (RubyString) value.callMethod("_dump", runtime.newFixnum(depthLimit)); dumpString(marshaled.getValue()); } + private void userNewMarshal(IRubyObject value) throws IOException { + out.write(TYPE_USRMARSHAL); + } + public void dumpString(String value) throws IOException { dumpInt(value.length()); out.write(RubyString.stringToBytes(value)); Index: src/org/jruby/runtime/builtin/meta/TimeMetaClass.java =================================================================== RCS file: /cvsroot/jruby/jruby/src/org/jruby/runtime/builtin/meta/TimeMetaClass.java,v retrieving revision 1.2 diff -u -r1.2 TimeMetaClass.java --- src/org/jruby/runtime/builtin/meta/TimeMetaClass.java 26 Mar 2006 21:21:40 -0000 1.2 +++ src/org/jruby/runtime/builtin/meta/TimeMetaClass.java 31 Mar 2006 11:04:13 -0000 @@ -76,6 +76,7 @@ defineSingletonMethod("mktime", Arity.optional(), "new_local"); defineSingletonMethod("utc", Arity.optional(), "new_utc"); defineSingletonMethod("gm", Arity.optional(), "new_utc"); + defineSingletonMethod("_load", Arity.optional(), "s_load"); // Missing getgm, getlocal, getutc (alias of getgm), gmt_offset, gmtoff (alias of // gmt_offset), utc_offset (alias of gmt_offset) @@ -115,6 +116,7 @@ defineMethod("localtime", Arity.noArguments()); defineMethod("hash", Arity.noArguments()); defineMethod("initialize_copy", Arity.singleArgument()); + defineMethod("_dump", Arity.optional(),"dump"); } }; @@ -169,6 +171,10 @@ public RubyTime new_utc(IRubyObject[] args) { return createTime(args, true); } + + public RubyTime s_load(IRubyObject[] args) { + return null; + } private static final String[] months = {"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"};