Trouble advancing date attribute

Try this:

@client.update_attribute(: date_due, new_date_due.to_s(:db))

-Bill

That is odd. I am using MySQL as well and I have no issues using the
same code. If you send the new_date_due to the log using:

logger.debug "The new date is #{new_date_due.to_s(:long)}"

Do you see the proper date being logged? That will at least tell us if
the problem is in your date calculation or in the update_attribute.

-Bill

Yes, I was just looking at that. The + method for dates takes an
argument of days, so I bet this works:

new_date_due = @client.date_due + 30
@client.update_attribute(: date_due, new_date_due)

-Bill

If you need it one month to the day rather than x days, this works

old_due = @client.date_due
@client.update_attribute(: date_due, Date.new(old_due.year,
old_due.month + 1, old_due.day))

-Bill

Yep, I was just writing up another email about the year bug I added. I
do something similar when generating saved reports using date ranges.
I use mysql's built in date functions like this one:

select DATE_ADD('2007-01-02', INTERVAL 1 MONTH);

You can see a full list here:
http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_adddate

I actually pass in a string something like:

Client.update(@client.id, "date_due =
DATE_ADD('#{@client.date_due.to_s(:db)}', INTERVAL 1 MONTH)")

I don't actually use it with update_attributes, but rather with a
select, but this should work. Note that update skips any validation or
other callbacks, but if that doesn't matter and you don't care that
this ties you to mysql, this will do what you want. There are bound to
be other ways, but this is pretty easy.

-Bill

I think i'd rather do
new_due = old_due >> 1

If you are going to roll your own version you need to worry about things like adding a month to the 31st of august (your code will try and set the date to the 31st of september, which will fail.
:slight_smile:

Fred

Thanks, thats great. I knew there had to be a way to do it, but I have
missed that operator when looking at the docs. Thanks again.

-Bill

Frederick Cheung wrote:

That is definitely the problem

30.days evaluates to the number of seconds in 30 days (ie 30*86400 = 2592000)

This is great when you're working with an instance of Time because + is used to mean 'add this many seconds'. However, for Date, + means 'add this many days'.
So Date.new(2007,11,12) + 30.days is actually add 2592000 days (around 7100 years).

Fred

Thanks guys. The "+ 30.days" was indeed the problem. "+ 30", as you
suggested Bill, took care of that. Ideally I would like to advance
date_due in terms of months (not sure if that's practical) and limit the
initial date_due to between the 1st and the 28th of a month. Anyone know
of a clean way to do this?

Thanks again for the help guys. This will work for now anyway :slight_smile:

Try new_date_due = @client.date_due >> 1

Date#+ takes a number of days as the argument.

Date#>> returns a new date "right shifted" some number of months.
use Date#<< to get a date some number of months ago.

shadowfax:~/Documents/terralien/dltsolutions/enrollnow rick$ qri "Date#>>"
---------------------------------------------------------------- Date#>>

Although this has been cleared up, there is the further issue related
to just moving a Time object 30.days because of the differences in
month length. I don't believe anyone has mentioned the Rails magic of
"next_month" and "previous_month".

Here is some stuff from console that shows what I'm talking about. The
first set uses Date. You'll see that adding months doesn't work but
days does.

# set time to current time

time = Time.now.utc

=> Mon Nov 12 12:32:07 UTC 2007

# make a date object with the previously set time

x = Date.parse("#{time}")

=> #<Date: 4908833/2,0,2299161>

x.strftime("%D")

=> "11/12/07"

# attempt to add 1.months to x

y = x + 1.months

=> #<Date: 10092833/2,0,2299161>

y.strftime("%D")

=> "07/09/04"

# attempt to add 30 to x
# this works because it is expecting days.
# this could work for now, but the time calculations you'll have to
# perform later make this a hassle as you might have been finding out

z = x + 30

=> #<Date: 4908893/2,0,2299161>

z.strftime("%D")

=> "12/12/07"

Yep, we found that around the beginning of the thread and Fredrick
pointed out the << and >> methods of Date which does
exactly what he wanted. I didn’t know about previous_month or
next_month. They are definitely more clear and self documenting,
although << and >> are part of ruby base so they will work
w/ calculations outside of rails. Looks to me like they do the exact
same thing.

-Bill

wrote:

Hmm, is next_month and previous_month something you added or something
added by a plugin you are using. I grepped my rails directory and I get
nothing back. I tried it in console and get a no method error. I tried
it in a view, same undefined method, however, << and >>
work everytime. I also search the docs and the api docs, and nothing.

Date.today >> 1 = 2007-12-15

-Bill

William Pratt wrote:

Hmm, is next_month and previous_month something you added or
something added by a plugin you are using. I grepped my rails
directory and I get nothing back. I tried it in console and get a no
method error. I tried it in a view, same undefined method, however,
<< and >> work everytime. I also search the docs and the api docs,
and nothing.

They are part of active support, and are defined in Time only, not Date.

Fred

Cool, thanks. I didn’t try Time since we were working with date
objects.

-Bill

Frederick Cheung wrote: