Forum: Ruby on Rails Very simple Date math goes randomly bonkers

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Matt D. (Guest)
on 2008-12-08 20:56
(Received via mailing list)
I have a "timesheet" in my app that simply displays the week range
based on a passed in date (params[:date]).
The view iterates through the Date::ABBR_DAYNAMES and shows a link to
the corresponding date.

Trouble is that about 40% of the time the calculated dates go bonkers.
Am I missing something?

Model:
  # Get a date range of the week that a particular date falls in
  # This is broken out like mad for diagnostics
  def self.get_work_week_date_range(date)
    monday   = date.monday
    sunday   = monday - 1.day
    eow      = date.end_of_week
    saturday = eow - 1.day

    dates = [sunday, saturday]

    logger.info
(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
    logger.info(">>>>> #{date}.monday = #{monday}")
    logger.info(">>>>> #{monday}-1.day = #{sunday}")
    logger.info(">>>>> #{date}.end_of_week = #{eow}")
    logger.info(">>>>> #{eow}-1.day = #{saturday}")
    logger.info(">>>>> #{date} == [#{dates[0]}, #{dates[1]}]")
    logger.info
(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")

    dates
  end

Logger output:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>> 2008-12-08.monday = 2008-12-08
>>>>> 2008-12-08-1.day = 2008-12-07
>>>>> 2008-12-08.end_of_week = 2008-12-14
>>>>> 2008-12-14-1.day = 2008-12-13
>>>>> 2008-12-08 == [2008-12-07, 2008-12-13]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

... n times later ...
Philip H. (Guest)
on 2008-12-08 21:16
(Received via mailing list)
On Dec 8, 2008, at 10:55 AM, Matt D. wrote:

>
> I have a "timesheet" in my app that simply displays the week range
> based on a passed in date (params[:date]).
> The view iterates through the Date::ABBR_DAYNAMES and shows a link to
> the corresponding date.

What do you pass to get_work_week_date_range?  Is it a string?  Or an
instance of Date?  Or Time?

If it worked once it should always work.  Which suggests that maybe
you're passing in something different from time to time?  One time a
Date, one time a Time?

Maybe?

Put together a test and explicitly pass the *same* argument (class and
value) and see if you can duplicate it.
Matt D. (Guest)
on 2008-12-08 21:30
(Received via mailing list)
> What do you pass to get_work_week_date_range?  Is it a string?  Or an  
> instance of Date?  Or Time?

I pull the date in from the params hash, and immediately parse it to a
Date:
Date.parse(params[:date]) rescue Date.today

> If it worked once it should always work.  Which suggests that maybe  
> you're passing in something different from time to time?  One time a  
> Date, one time a Time?

You're right, that's why I've pounded my head against the wall for a
week!
This method is only called from one other method, and I've extracted
it really only for testing.

> Put together a test and explicitly pass the *same* argument (class and  
> value) and see if you can duplicate it.

All tests pass :(

  it "should know how to get the week based on a date" do
    TimeCard.get_work_week_date_range(Date.parse("2008-08-05")).should
== [Date.parse("2008-08-03"), Date.parse("2008-08-09")]
    TimeCard.get_work_week_date_range(Date.parse("2008-01-01")).should
== [Date.parse("2007-12-30"), Date.parse("2008-01-05")]
    TimeCard.get_work_week_date_range(Date.parse("2008-02-29")).should
== [Date.parse("2008-02-24"), Date.parse("2008-03-01")]
    TimeCard.get_work_week_date_range(Date.parse("2007-02-28")).should
== [Date.parse("2007-02-25"), Date.parse("2007-03-03")]
  end
Frederick C. (Guest)
on 2008-12-08 22:15
(Received via mailing list)
On Dec 8, 6:55 pm, Matt D. <removed_email_address@domain.invalid> wrote:

>
>
> >>>>> 2008-12-08.monday = 2008-12-08
> >>>>> 2008-12-08-1.day = 1772-05-19
> >>>>> 2008-12-08.end_of_week = 3428-04-08
> >>>>> 3428-04-08-1.day = 3191-09-18
> >>>>> 2008-12-08 == [1772-05-19, 3191-09-18]

Perhaps the key thing to note is that 1772-05-19 is about 236 years
and 7 months ago, which (get your calculators out) is about 86400, ie
the number of seconds in a day. Whereas on an instance of Time, +/- 1
means +/- 1 second, on instances of Date/DateTime +/- means +/- 1
second. That is I suspect the basic problem.

On newer versions of rails, things like 1.day are smart enough to do
the right thing whether or not you add a date or a Time to them (the +
method on Date is overriden to check if the argument is a thing like
1.day).
Somewhere this has gone wrong. If you have any plugins that mess with
dates (or if you've being doing stuff like that yourself) then I'd
have a look at those - it could be something like once some random
model is loaded some extensions to Date are pulled in at that point
and from then onwards calculations are borked.

Fred
Matt D. (Guest)
on 2008-12-08 22:41
(Received via mailing list)
> Perhaps the key thing to note is that 1772-05-19 is about 236 years
> and 7 months ago, which (get your calculators out) is about 86400, ie
> the number of seconds in a day. Whereas on an instance of Time, +/- 1
> means +/- 1 second, on instances of Date/DateTime +/- means +/- 1
> second. That is I suspect the basic problem.

Man, good call.

> On newer versions of rails, things like 1.day are smart enough to do
> the right thing whether or not you add a date or a Time to them (the +
> method on Date is overriden to check if the argument is a thing like
> 1.day).

I'm using 2.2.2, but...

> Somewhere this has gone wrong. If you have any plugins that mess with
> dates (or if you've being doing stuff like that yourself) then I'd
> have a look at those - it could be something like once some random
> model is loaded some extensions to Date are pulled in at that point
> and from then onwards calculations are borked.

... I do monkeypatch Date, but I ensured that I wasn't actually
overriding any existing method.

Thanks for you help Fred, this smells like the right track.
Matt D. (Guest)
on 2008-12-09 00:05
(Received via mailing list)
It was the facets/time library. It was loaded in a totally separate
part of the app, in a method that had not much to do with anything.

Thanks again Frederick; that one got your a WWR recommendation ;)
This topic is locked and can not be replied to.