add/subtract with date!
[1/13] from: t_degrav::rhrk::uni-kl::de at: 14-Nov-2000 1:23
Ok, I'm not sure if this message came through the first time... :-(
_____________
Hi there!
I'm wondering how to calculate when using date! values...
As long as I only want to add/subtract a certain amount of DAYS there
seem to be no problems, but when it comes to MONTHS or YEARS it gets a
little comlicated. Or am I missing something simple here???
Let's say I have:
>> date: 14-Nov-2000
== 14-Nov-2000
Now it's easy to say:
>> newdate: date + 1
== 15-Nov-2000
>> newdate: date + 100
== 22-Feb-2001
>> newdate: date - 1
== 13-Nov-2000
>> newdate: date - 400
== 11-Oct-1999
So, even roll-overs to another month or year are recognized. That's great!
But how can I add/subtract exactly one month or one year?
Using a certain amount of days would depend on which month I start with.
>> newdate: date + ???
== 14-Dec-2000
>> newdate: date + ???
== 14-Nov-2001
>> newdate: date - ???
== 14-Oct-2000
>> newdate: date - ???
== 14-Nov-1999
As far as I can see right now there's no way to do that directly, so I
started experimenting with to-date.
Now I can do (parenthesis only included for better readability):
>> newdate: to-date reduce [date/day (date/month + 1) date/year]
== 14-Dec-2000
>> newdate: to-date reduce [date/day (date/month + 10) date/year]
== 14-Sep-2001
>> newdate: to-date reduce [date/day date/month (date/year + 1)]
== 14-Nov-2001
An overflow of the month is correctly recognized and the year adjusted.
But, when I try:
>> newdate: to-date reduce [date/day (date/month - 1) date/year]
== 14-Oct-2000
>> newdate: to-date reduce [date/day (date/month - 15) date/year]
== 14-Dec-23844
>> newdate: to-date reduce [date/day date/month (date/year - 1)]
== 14-Nov-1999
Wow, if I go back 15 months I jump ahead 21844 years! ;-)
Ok, when I think about how 'to-date might work (or better how 'to does) I
have to admit this result isn't very surprising...
Final question: Is there any easy way of adding/subtracting months or years
without having to check for boundaries myself???
TIA,
Tom
[2/13] from: holger:rebol at: 14-Nov-2000 9:17
On Tue, Nov 14, 2000 at 08:55:19AM -0700, Russell Yost wrote:
> Curiouser and curiouser!
> A console session:
<<quoted lines omitted: 11>>
> >>
> So far I haven't figured out how this happens!
Looks like correct behavior. In the second example before you change the month
the year is 2002. Then you set the month to "November + 15 months", i.e. REBOL
normalizes the date to "November + 15 months + year 2002" and correctly ends
up with February 2004.
--
Holger Kruse
[holger--rebol--com]
[3/13] from: t_degrav:rhrk:uni-kl at: 14-Nov-2000 19:00
Hi Russel,
maybe I have the explanation:
When you think of date as having the three components day, month and year
you don't directly change the whole date with "today/month: now/month + 15"
but only the month! So you get 14-26-2000, which means more or less the
14th day of the 26 month(!) of the year 2000. Rebol recognizes that this
isn't a valid date, but is able to calculate a corresponding date: 14-2-2002.
If you now repeat "today/month: now/month + 15" you first get 14-26-2002.
This is then transformed to 14-2-2004. Maybe you confused yourself a little
by mixing today and now? Try today/month: today/month + 15, then you get
the result you possibly expected, the date increases exactly 15 months.
This maybe confusing at first but comes in rather handy when you want to
add a certain amount of months instead of days. The only thing I miss is
the automatic conversion of negative month values to preceding years.
Tom
Russell Yost wrote:
[4/13] from: brett:codeconscious at: 15-Nov-2000 12:03
> This maybe confusing at first but comes in rather handy when you want to
> add a certain amount of months instead of days. The only thing I miss is
> the automatic conversion of negative month values to preceding years.
>
Yes it would be nice if that bug was fixed. Before that occurs here's a
workaround.
add-months: function [
"Offsets a date using a number of months (positive or negative)."
date [date!]
months [integer!]
] [result-date delta-years delta-months] [
delta-years: to-integer divide months 12
delta-months: remainder months 12
if lesser? delta-months 0 [
delta-years: subtract delta-years 1
delta-months: add delta-months 12
]
result-date: date
result-date/year: add result-date/year probe delta-years
result-date/month: add result-date/month probe delta-months
return result-date
]
Brett.
[5/13] from: rryost:home at: 14-Nov-2000 8:55
Curiouser and curiouser!
A console session:
>> today: now
== 14-Nov-2000/8:37:21-7:00
>> today/month: now/month + 15
== 26 ; oops! but --
>> today
== 14-Feb-2002/8:37:21-7:00 ; somehow, the error was corrected! But let's
try again:
>> today/month: now/month + 15
== 26
>> today
== 14-Feb-2004/8:37:21-7:00
>>
So far I haven't figured out how this happens!
Russell [rryost--home--com]
[6/13] from: rryost:home at: 14-Nov-2000 9:05
In my preceding post, REBOL version:
REBOL/Core 2.3.0.3.1
Also, note in the second "try" of today/month: today/month + 15, the year
incremented by 2, but the month did not change. The result was as though I
had used 24 instead of 15.
Russell [rryost--home--com]
[7/13] from: allen:rebolforces at: 14-Nov-2000 18:47
Hi Tom,
REBOL makes it exceptionally easy to do.
.
date: 14-Nov-2000
date/day: date/day + 10
print date
24-Nov-2000
date/month: date/month + 3
print date
24-Feb-2001
date: 14-Nov-2000
date/year: date/year - 1
print date
14-Nov-1999
Only thing to watch is a bug in month subtraction. It goes flaky if you
subtract prior to January . (Hopefully will be fixed soon Feedback #4014)
date: 14-Nov-2000
date/month: date/month - 12
print date
14-Mar-23845
But subtraction using days does not have this problem
date: 14-Nov-2000
date/day: date/day - 366
print date
14-Nov-1999
----- >
> Final question: Is there any easy way of adding/subtracting months or
years
> without having to check for boundaries myself???
Have a look at the calendar style script on my Rebsite, you will find a
comment in that script where I handle the bug.
Cheers,
Allen K
[8/13] from: brett:codeconscious at: 15-Nov-2000 15:17
Oops left in a couple of unnecessary "probes" at the end of my add-months
function - just delete them.
Also, while we are playing around with dates I thought I'd pass on another
function too.
Rebol allows you to add a time to a date. Like so
>> start-time: now
== 15-Nov-2000/15:13:59+11:00
>> end-time: start-time + 2:00
== 15-Nov-2000/17:13:59+11:00
But you cannot get the time interval using a simple operator (correct me if
I'm wrong)
>> end-time - start-time
== 0
But using my datetime-subtract function you can
>> datetime-subtract end-time start-time
== 2:00
Here 'tis (expanded for readability)
datetime-subtract: function [
"Subract one date from another returning time between them."
a [date!]
b [date!]
][delta-days delta-hhmmss a-hhmmss b-hhmmss]
delta-days: subtract a/date b/date
a-hhmmss: either a/time [a/time][00:00:00]
b-hhmmss: either b/time [b/time][00:00:00]
return add multiply 24:00:00 delta-days (subtract a-hhmmss b-hhmmss)
]
Brett.
[9/13] from: jgoodnow:pacbell at: 13-Nov-2000 22:57
At 01:23 AM 11/14/2000 +0100, you wrote:
>I'm wondering how to calculate when using date! values...
>
>As long as I only want to add/subtract a certain amount of DAYS there
>seem to be no problems, but when it comes to MONTHS or YEARS it gets a
>little comlicated. Or am I missing something simple here???
Hi Tom,
Try:
date/month: date/month + 1
Hope this helps.
- jim
[10/13] from: arolls:bigpond:au at: 14-Nov-2000 18:57
Jim Goodnow II wrote:
> At 01:23 AM 11/14/2000 +0100, you wrote:
> >I'm wondering how to calculate when using date! values...
<<quoted lines omitted: 7>>
> Hope this helps.
> - jim
Jim,
There is a problem with subtraction.
Example:
>> date: 14-Jan-2001
== 14-Jan-2001
>> date/month: date/month - 1
== 0
>> date
== 14-Apr-23846
Anton.
[11/13] from: t_degrav:rhrk:uni-kl at: 14-Nov-2000 12:52
Thanks, Kim, Anton,
but...
Anton wrote:
> Jim Goodnow II wrote:
...
> > Try:
> >
<<quoted lines omitted: 12>>
> >> date
> == 14-Apr-23846
That's only part of the problem...
Jim's solution does look very simple, but it doesn't work at all:
>> date
== 14-Nov-2000
>> date/month: date/month + 1
== 14-Dec-2000
>> date
== 14-Nov-2000
Tom
[12/13] from: t_degrav:rhrk:uni-kl at: 14-Nov-2000 14:08
Hi,
Tom De Grave wrote:
> Jim's solution does look very simple, but it doesn't work at all:
> >> date
<<quoted lines omitted: 3>>
> >> date
> == 14-Nov-2000
Hm, after reading Brett's first message in the "Set-words and refinements"
thread I noticed that I was still working with /core 2.2! Silly me!
Well, the above DOES work with 2.3, but the problem with the boundaries
when subtracting still remains!
Any ideas?
Thanks,
Tom
[13/13] from: brett:codeconscious at: 15-Nov-2000 0:11
On the contrary, works fine here (REBOL/View 0.10.38.3.1 31-Oct-2000)
>> date: 14-nov-2000
== 14-Nov-2000
>> date/month
== 11
>> date/month: date/month + 1
== 12
>> date
== 14-Dec-2000
>> date/month: date/month + 1
== 13
>> date
== 14-Jan-2001
But, as Jim said subtraction doesn't.
BTW Jim have you submitted this to feedback?
Brett.
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted