ruby soap datatime adds Z at the end - ruby-on-rails

I have some strange behavior with ruby.
In a rake file I pass in a date to soap method. In the response it appends a Z at the end of the date.
in a lib file, same thing, same requirements, it doesn't.
I need the case where it doesn't. It executes the same.
What could it be?
<n1:startDate>2009-08-18T00:00:00-05:00Z</n1:startDate>
<n1:endDate>2009-08-26T00:00:00-05:00Z</n1:endDate>

The letter at the end is an indicator of the timezone (in this case UTC). The timestamp is in ISO8601 format (pretty much the standard now-a-days for all things internet), so I'm not sure why you'd want otherwise.
Without seeing the code that's generating it I'm not sure what more I can offer. Why do you want it without the 'Z'?

You've got an ISO 8601 formatted date there, the Z indicates 'Zulu' time or UTC, but not sure why you're getting differing formats though.

I am accessing an API which doesn t support this ISO standard. The date should not have a Z at the end. but when the soap response is build, it adds it. And I don t send it with that Z .. as I pass it to the web method.
Here is the code
factory = SOAP::WSDLDriverFactory.new(WSDL_STATS)
driver = factory.create_rpc_driver
driver.wiredump_dev = STDOUT
response = driver.getAllLeads({"pubID" => AFF_ID_TEST, "startDate" => start_date, "endDate" => end_date})
The end date that are passed, tried various .. isn t with that Z , from zone, at the end.
If I overwritte the zone method, maybe it will work, but I don t want to do that.
<n1:startDate>2009-08-18T00:00:00-05:00Z</n1:startDate>
<n1:endDate>2009-08-26T00:00:00-05:00Z</n1:endDate>
I pass the date without the Z, but when the soap is constructed the Z is added somehow.
This is what I want
<n1:startDate>2009-08-18T00:00:00-05:00</n1:startDate>
<n1:endDate>2009-08-26T00:00:00-05:00</n1:endDate>
Thank you ;)

Related

How can i remove the milliseconds from date time in rails?

I have to compare the date in rails to get the values after that date I have send the date as "2013-03-04T06:26:25Z"but actually the record in the db contains date as follows 2013-03-04 06:26:25.817149 so when i check with the date it also returns that record but i want records after that date. how can i remove the milliseconds from the db? please help me.
I had a similar problem
Update your time object like this before sending it to the database :
time.change(:usec => 0)
Since ruby 1.9 you can use round
t = Time.now.round
t.usec # => 0
I was also having this problem, however when I was applying the change as indicated in #Intrepidd's answer, it wasn't affecting the microseconds of my time object.
Please note that (at least currently) the :usec key only works with the Time#change method, and not with the DateTime#change method.
The DateTime#change method ignores the keys that it doesn't accept, so you wouldn't be able to tell that your attempted change of the microseconds didn't work unless you inspected the object further (such as with DateTime#rfc3339(9)).
So before you attempt this change, make sure that you are working with a Time object, not a DateTime object.

How can I use US-style dates in Rails using Ruby 1.9?

I'm in the U.S., and we usually format dates as "month/day/year". I'm trying to make sure that my Rails app, using Ruby 1.9, assumes this format everywhere, and works the way it did under Ruby 1.8.
I know that lots of people have this issue, so I'd like to create a definitive guide here.
Specifically:
'04/01/2011' is April 1, 2011, not Jan 4, 2011.
'4/1/2011' is also April 1, 2011 - the leading zeros should not be necessary.
How can I do this?
Here's what I have so far.
Controlling Date#to_s behavior
I have this line in application.rb:
# Format our dates like "12/25/2011'
Date::DATE_FORMATS[:default] = '%m/%d/%Y'
This ensures that if I do the following:
d = Date.new(2011,4,1)
d.to_s
... I get "04/01/2011", not "2011-04-01".
Controlling String#to_date behavior
ActiveSupport's String#to_date method currently looks like this (source):
def to_date
return nil if self.blank?
::Date.new(*::Date._parse(self, false).values_at(:year, :mon, :mday))
end
(In case you don't follow that, the second line creates a new date, passing in year, month and day, in that order. The way it gets the year, month and day values is by using Date._parse, which parses a string and somehow decides what those values are, then returns a hash. .values_at pulls the values out of that hash in the order Date.new wants them.)
Since I know that I will normally pass in strings like "04/01/2011" or "4/1/2011", I can fix this by monkeypatching it like this:
class String
# Keep a pointer to ActiveSupport's String#to_date
alias_method :old_to_date, :to_date
# Redefine it as follows
def to_date
return nil if self.blank?
begin
# Start by assuming the values are in this order, separated by /
month, day, year = self.split('/').map(&:to_i)
::Date.new(year, month, day)
rescue
# If this fails - like for "April 4, 2011" - fall back to original behavior
begin
old_to_date
rescue NoMethodError => e
# Stupid, unhelpful error from the bowels of Ruby date-parsing code
if e.message == "undefined method `<' for nil:NilClass"
raise InvalidDateError.new("#{self} is not a valid date")
else
raise e
end
end
end
end
end
class InvalidDateError < StandardError; end;
This solution makes my tests pass, but is it crazy? Am I just missing a configuration option somewhere, or is there some other, easier solution?
Are there any other date-parsing cases I'm not covering?
Gem: ruby-american_date
This gem was created since I asked this question. I'm now using it and have been pleased.
https://github.com/jeremyevans/ruby-american_date
Date.strptime is probably what you're looking for in ruby 1.9.
You're probably stuck monkeypatching it onto string.to_date for now, but strptime is the best solution for parsing dates from strings in ruby 1.9.
Also, the formats are symmetric with strftime as far as I know.
you can use rails-i18n gem or just copy the en-US.yml and set your default locale "en-US" in config/application.rb
For parsing US-style dates, you could use:
Date.strptime(date_string, '%m/%d/%Y')
In console:
> Date.strptime('04/01/2011', '%m/%d/%Y')
=> Fri, 01 Apr 2011
> Date.strptime('4/1/2011', '%m/%d/%Y')
=> Fri, 01 Apr 2011
Use REE? :D
Seriously though. If this is a small app you have complete control over or you are standardizing on that date format, monkey patching for a project is totally reasonable. You just need to make sure all your inputs come in with the correct format, be it via API or website.
Instead of using to_s for Date instances, get in the habit of using strftime. It takes a format string that gives you complete control over the date format.
Edit:
strptime gives you full control over the parsing by specifying a format string as well. You can use the same format string in both methods.
Another option is Chronic - http://chronic.rubyforge.org/
You just need to set the endian preference to force only MM/DD/YYYY date format:
Chronic::DEFAULT_OPTIONS[ :endian_precedence ] = [ :middle ]
However the default for Chronic is the out-of-order US date format anyway!

Working with and testing dates in rails

My application uses dates a lot. A lot of ajax calls and urls involve datetimes and I find the typical format '1920-10-10 18:30:00' to be unfriendly for these purposes. I work around this by creating a helper method that basically strips the unnecessary characters out of the date (192010101830) and another method for converting the string back in to a date object.
When I build a url it goes something like this:
=link_to "Send Date", thing_my_date_path(date_to_string(DateTime.now))
Then when the thing_date action receives, it converts the parameter back in to a datetime object
def my_date
#date = string_to_date(params[:mydate])
....
end
This works fine in development. However I am completely open to other suggestions.
The problem is when I go to test my application. Tests fail because the helper methods for date_to_string and string_to_date are not present. I could include them in the tests but I feel like they should be kept separate.
So I'm looking for
a) a better way to pass dates around, and more importantly
b) a method of testing an action that is dependent on helper methods.
There are built-in methods for that methinks.
> DateTime.now.to_s(:number)
=> "20110429162748"
> DateTime.parse("20110429162748")
=> Fri, 29 Apr 2011 16:27:48 +0000
Hope that helps..

Ruby: How do you convert a time or date to a friendly url string?

For instance, if I have a Time.now, how would I convert that to a friendly url string?
Time.now.some_method_here => some_url_friendly_string_here
I believe there is a built-in Ruby method to do so, but I can't seem to locate it on Google. Any ideas?
As you're using Rails (as indicated by your tag), you can use .to_s:
Time.now.to_s
You can specify a time format to the method, which will format the string differently, such as Time.now.to_s(:db). Please see this link for the default date formats. If you don't specify a format, it'll use the same as strftime.
The next part of that page also describes how to add your own time formats, which is very simple:
# Initializer
Time::DATE_FORMATS[:month_and_year] = "%B %Y"
# Any code
Time.now.to_s(:month_and_year) # => September 2010
Everything in ruby is open and extensible
class Time
def to_url_string
self.strftime("%H:%M:%s")
end
end
You can use the strftime method. It's a bit cryptic, but if you look at the docs, you can pick out the year, month, day, etc.
For example, Time.now.strftime("%H:%M:%s") will give the time in hours, minutes and seconds.
You might consider using the xmlschema method which will return a date/time in the format:
CCYY-MM-DDThh:mm:ssTZD
or
CCYY-MM-DDThh:mm:ss.sssTZD
depending on the value of the fraction_digits argument.
This would give you a time like:
2010-09-15T20:31:15+05:00
for example.
See the docs for more info and a link to the code.

How do I work with Time in Rails?

I've been pulling my hair out trying to work with Time in Rails. Basically I need to set all time output (core as well as ActiveSupport) to the server's local time -- no GMT, no UTC, etc. I've seen various posts relating to Time, but they usually involve someone's need to set it for each user. Mine isn't nearly as complex, I simply want consistency when I use any Time object. (I'd also appreciate not receiving errors every 3 seconds telling me that I can't convert a Fixnum (or some other type) to string -- it's Ruby, just do it!)
I also seem to be getting drastically different times for Time.new vs the ActiveSupport 1.second.ago. Anyway, does anyone have any quality suggestions as regards working with Time in Rails?
If you just want Time objects to be consistent, then why not stick with UTC? I just tried Time.new and 1.second.ago using script/console and I get the same output (give or take a second for typing the command). How are you doing it?
Somewhere in your initializers, define the format(s) that you want to use.
ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.merge!(:default => '%m/%d/%Y %H:%M')
ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.merge!(:my_special_format => '%H:%M %p')
Then when you want to print a Time object, it works like the following example. Notice that the Time object in my console is already aware of my time zone. I'm not performing any magical transformations here.
>> t = Time.now
=> Wed Jul 15 18:47:33 -0500 2009
>> t.to_s
=> "07/15/2009 18:47"
>> t.to_s(:my_special_format)
=> "18:47 PM"
Calling Time#to_s uses the :default format, or you can pass in the name of the format you'd rather use like I did with :my_special_format.
You can see the various options for formatting a Time object here.
If u don't want to store each user time setting, the only solution is to use javascript time system because it work on user client time. For example i have an application that each time user try it, the app will create some example data with each data have a initial date value "today". At first time, it confuse me a lot because my host server is in australia and lot of user is on western part, so sometime the initial date value is not "today", it said "yesterday" because of different time region.
After a couple day of headache i finally take decision to JUST use javascript time system and include it in the link, so when user click the "try now" link it will also include today date value.
<% javascript_tag do -%>
var today = new Date();
$("trynow").href = "<%= new_invitation_path %>?today=" + today.toLocaleString();
<% end -%>
Add the following to config/environment.rb to handle time correctly and consistently all the time within the context of Rails. It's important to know that it will store your times to the database in UTC -- but this is what you want -- all the conversion is done automatically.
config.time_zone = 'Pacific Time (US & Canada)'
You can run rake time:zones:local from your Rails root directory to get a list of valid time zone strings in your area.
A quick addition to the DATE_FORMAT solution posted above. Your format can be a string, in which case it works as noted above by calling strftime, but you can also define the format as a lambda:
CoreExtensions::Time::Conversions::DATE_FORMATS.merge! :my_complex_format => lambda {|time|
# your code goes here
}

Resources