Yes. Modifying the date is not my intention in this example.
But say it were. Say I were to to modify the current date to some date in
the future. A simple reversal of steps will not give me the original value
for certain dates.
Can something else be done to make such a calculation reversible?
irb(main):006:0> d = Date.parse('31-03-2016')
=> #<Date: 2016-03-31 ((2457479j,0s,0n),+0s,2299161j)>
irb(main):008:0> d = d + 30
=> #<Date: 2016-04-30 ((2457509j,0s,0n),+0s,2299161j)>
irb(main):009:0> d - 30
=> #<Date: 2016-03-31 ((2457479j,0s,0n),+0s,2299161j)>
···
On Tue, 2016-04-05 at 19:57 +0530, Saurav Kothari wrote:
Yes. Modifying the date is not my intention in this example.
But say it were. Say I were to to modify the current date to some date in the
future. A simple reversal of steps will not give me the original value for
certain dates.
Can something else be done to make such a calculation reversible?
Reid, the examples you have demonstrated are calculations where you add and
*substract* *days *which will certainly be reversible.
But in the event of adding/subtractin *month *(as in the first thread), you
can see that the operation is not reversible. Can that be made reversible?
We already use a system where we set a future date (+ 1.month) for further
actions and do not store the original date. We use -1.month to get the
original date whenever we need it but that fails for a few cases as shown.
We could migrate to adding/subtracting 30.days in the future but how do we
handle existing date?
Thank you @Martin for putting it like I was intending to. I put up a wrong
example in the original post.
@Marcus: yes this is indeed the quirk that has me puzzled. So that is just
how it works internally. Will have to explore other options (like +/-
30.days).
I believe he is referring to the fact that Date("2016-03-31") + 1.month -
1.month = Date("2016-03-30"). I don't see what can be done about that,
since two days in March (30, 31), map to a single day in April (30), so the
mapping is clearly not reversible.
martin
···
On Tue, Apr 5, 2016 at 10:32 AM, <sto.mar@web.de> wrote:
Am 05.04.2016 um 17:34 schrieb Saurav Kothari:
> Reid, the examples you have demonstrated are calculations where you add
> and *substract* /days /which will certainly be reversible.
> But in the event of adding/subtractin /month /(as in the first thread),
> you can see that the operation is not reversible. Can that be made
> reversible?
Saurav, you did _not_ show in your first post that the operation is
not reversible, you added / subtracted 1.month from the same date
(2016-03-31), because the original date saved in d was not changed,
as Bryce already pointed out.
Note also that Integer#month is not part of Ruby core or stdlib.
So without knowing what gems you required it's not easy to check
your example:
$ irb
2.3.0 :001 > require "date"
=> true
2.3.0 :002 > d = Date.parse('31-03-2016')
=> #<Date: 2016-03-31 ((2457479j,0s,0n),+0s,2299161j)>
2.3.0 :003 > d = d + 1.month # NoMethodError !!!
Saurav, you did _not_ show in your first post that the operation is
not reversible, you added / subtracted 1.month from the same date
(2016-03-31), because the original date saved in d was not changed,
as Bryce already pointed out.
Note also that Integer#month is not part of Ruby core or stdlib.
So without knowing what gems you required it's not easy to check
your example:
$ irb
2.3.0 :001 > require "date"
=> true
2.3.0 :002 > d = Date.parse('31-03-2016')
=> #<Date: 2016-03-31 ((2457479j,0s,0n),+0s,2299161j)>
2.3.0 :003 > d = d + 1.month # NoMethodError !!!
(I assume that's what you meant to do.)
You are possibly using Rails?
Regards,
Marcus
···
Am 05.04.2016 um 17:34 schrieb Saurav Kothari:
Reid, the examples you have demonstrated are calculations where you add
and *substract* /days /which will certainly be reversible.
But in the event of adding/subtractin /month /(as in the first thread),
you can see that the operation is not reversible. Can that be made
reversible?
The problem of working with durations is that what a month is is
ill-defined in that sense. So the designer of the API needs to define
something that makes sense in edge cases.
For example, the intention of adding a month is generally speaking to
increment the month number in the date, or reset to 1 if 12 incrementing
the year.
But that leaves you with situations like adding a month to 31 March,
because 31 April does not exist. You need to define what to do there, and
the choice is to keep the "increment the month by one", rather than jumping
to May. For that to be possible, the natural choice is "same day or end of
the month".
And that implies that for some dates, adding a month gives the same date.
Therefore you cannot reverse that unless you store the original value.
You need to get the business rule right taking this ambiguity into account.
For example, if the app switches to 30.days then it has to be OK that 1
July yields 31 July, and that 31 January may yield 2 March.
The Active Support Core Extensions guide documents edge cases of these APIs.
On Wed, 6 Apr 2016 at 08:17, Saurav Kothari <sauravkothari2@gmail.com> wrote:
Thank you @Martin for putting it like I was intending to. I put up a wrong
example in the original post.
@Marcus: yes this is indeed the quirk that has me puzzled. So that is just
how it works internally. Will have to explore other options (like +/-
30.days).