SOAP Dates and Rails

Hi all,

I'm using ruby on rails to communicate with a JADE agent server over SOAP.

If I send over a DateTime.now it is accepted by the JADE server. As does 5.minutes.since DateTime.now and such.

But if I pull a datetime out of a rails model and try to send that over I get an error. How to I convert rails model's datetime to the whatever format DateTIme.now is producing that works perfectly.

Thanks.. I could hack up the string.. but i'm assuming there is some simple way to do this...

working format (p DateTime.now):

Tue, 29 Sep 2009 22:42:43 -0300

rails model not working format (p @seller.deadline #where seller is a model):

Tue, 29 Sep 2009 22:42:00 ADT -03:00

Thanks, Aaron Broad

Thanks Robert,

No such luck though... Time.now.xmlschema results in the following error:

SOAP::FaultError in SellersController#create

Error parsing element deadline. Unparseable date: "2009-09-30T14:40:01-03:00"

The think will only take The fomat with the 6 decimals after the seconds

And I can't for the life of me figure out why DateTime.now and ActiveRecord's datetime.to_datetime which also results in a DateTime... doesn't end up on the other side of soap4r with the decimal places.

if I send @seller.dealine.to_datetime over soap it fails to include the the microseconds... but if i do this awful hack it works: @seller.deadline.to_datetime + DateTime.now.sec_fraction

I agree the SOAP server on the other side should be able to handle a missing a missing microseconds.. but alas it does not.. its the Web Service Integration Gateway for the Java Agent Development Environment. I'm loathe to try and hack it, but could I guess.

It just seems to me.. if you got two DateTimes and you pass them over soap.. they either should both include microseconds or both not... but it doeesn't seem to be the case in ruby.. it seems to matter where your datetime came from... if it was a once a rails activerecord datetime.. thats had to_datetime called on it.. you're up a creek...

thanks again, Aaron

Disgustingly

@seller.deadline.to_datetime + 0.000000

also works!

it results in: 2009-09-30T15:01:59.9999928474453144-03:00

which is accepted. The actual date reading on the other side appears to be happening inside xerces I believe, in source i don't have, which is called by the WSIG by JADE.

So it would appear as though it simply requires some fractional digits of any length to follow the time.

However it totally bungles that the conversion of that date.. because it is then converted into the Java date of: Sat Sep 19 20:22:48 ADT 2009

Meanwhile @seller.deadline.to_datetime + DateTime.now.sec_fraction results in:

2009-09-30T15:02:00.871607-03:00

which ends up inside java as: Wed Sep 30 15:16:31 ADT 2009

So all fubared up.

I'm going to e-mail them because obviously their library is messed. But I'd still like some explanation as to when and when not the soap will include some microseconds.

thanks, Aaron

Final solution is as follows: @seller.deadline.to_datetime.strftime (fmt='%FT%T.000')

gross but works and is parsed correctly.. I guess it silly JADE wants exactly 3 zeros

Or even simpler:

@seller.deadline.strftime(fmt='%FT%T.000')@seller.deadline.strftime (fmt='%FT%T.000')

correctly formats a ActiveRecord DateTime for SOAP communication with JADE java agent system.

Aaron Broad wrote:

Or even simpler:

@seller.deadline.strftime(fmt='%FT%T.000')@seller.deadline.strftime (fmt='%FT%T.000')

correctly formats a ActiveRecord DateTime for SOAP communication with JADE java agent system.

Yep, there's not much you can do about a mangled server-side implementation. Believe me I've had to do much uglier things with some of the integrations I've had to deal with. I'll be quite happy when the world wakes up and realizes that SOAP was a horrible idea, implemented very poorly in nearly every case.

Aaron Broad wrote:

@seller.deadline.strftime(fmt='%FT%T.000')@seller.deadline.strftime (fmt='%FT%T.000')

By the way, I think in a case like yours I would go ahead and reopen the Time (and possibly Date) classes and add your special formatter method so you don't have to keep repeating your strftime("ugliness") all the time.

Then you could just to something like: myTime.xmljade

Great Idea.... had to google what you meant... here is my first go round

require 'date'

# reopen the class DateTime.class_eval do   def jadexml     self.strftime(fmt='%FT%T.000')   end end

p DateTime.now.jadexml

works perfectly...

now as far as rails goes.. where is the appropriate place to put such a "re-opening"

Super improved:

require 'date' require 'rubygems' require 'active_record'

module RubyToJadeXML   def jadexml     self.strftime(fmt='%FT%T.000')   end end

DateTime.class_eval do   include RubyToJadeXML end

ActiveSupport::TimeWithZone.class_eval do     include RubyToJadeXML end

p DateTime.now.jadexml p ActiveSupport::TimeZone.new("Atlantic Time (Canada)").now.jadexml

Thanks again, Now where would you recommend I put this in a Rails app? Aaron

Aaron Broad wrote:

Super improved:

require 'date' require 'rubygems' require 'active_record'

module RubyToJadeXML   def jadexml     self.strftime(fmt='%FT%T.000')   end end

DateTime.class_eval do   include RubyToJadeXML end

You don't need class_eval to reopen a class. Just use "class DateTime", same as if you were defining from scratch.

ActiveSupport::TimeWithZone.class_eval do     include RubyToJadeXML end

p DateTime.now.jadexml p ActiveSupport::TimeZone.new("Atlantic Time (Canada)").now.jadexml

Thanks again, Now where would you recommend I put this in a Rails app? Aaron

On Sep 30, 8:57�pm, Robert Walker <rails-mailing-l...@andreas-s.net>

Best,

Aaron Broad wrote:

Super improved:

require 'date' require 'rubygems' require 'active_record'

module RubyToJadeXML def jadexml    self.strftime(fmt='%FT%T.000') end end

DateTime.class_eval do include RubyToJadeXML end

You don't need class_eval to reopen a class. Just use "class DateTime", same as if you were defining from scratch.

Yes, the effect is the same. EXCEPT, that if the class isn't already defined, then doing DateTime.class_eval will cause Rails autoloading to be invoked or an exception to be thrown. I've seen this style of using class_eval in other places and this is one of those times where it makes perfect sense.

-Rob

ActiveSupport::TimeWithZone.class_eval do    include RubyToJadeXML end

p DateTime.now.jadexml p ActiveSupport::TimeZone.new("Atlantic Time (Canada)").now.jadexml

Thanks again, Now where would you recommend I put this in a Rails app? Aaron

On Sep 30, 8:57�pm, Robert Walker <rails-mailing-l...@andreas-s.net>

Best, -- Marnen Laibow-Koser http://www.marnen.org marnen@marnen.org --

Rob Biedenharn http://agileconsultingllc.com Rob@AgileConsultingLLC.com

Rob Biedenharn wrote:

end end

DateTime.class_eval do include RubyToJadeXML end

You don't need class_eval to reopen a class. Just use "class
DateTime", same as if you were defining from scratch.

Yes, the effect is the same. EXCEPT, that if the class isn't already defined, then doing DateTime.class_eval will cause Rails autoloading to be invoked or an exception to be thrown.

Good point. But does it matter here?

I've seen this style of using class_eval in other places and this is one of those times where it makes perfect sense.

Or not. It seems to me that, since we're extending Rails core classes here, we know that the rest of the class *will* get loaded. Do we care whether it does so before or after the module inclusion? In this case, I think not.

-Rob

app?

--

Rob Biedenharn http://agileconsultingllc.com Rob@AgileConsultingLLC.com

Best,