Say I am given a date start an increment step (possibly mixed radix) and a desired number of steps n. I would like to compute a date end that will satisfy Length[DateRange[start,end,step]]==n.

I can compute this date end with the following function.

f[{start_, Automatic,  step_}, n_]:= Nest[DatePlus[#, step] &, start, n - 1]

This works nicely in examples where n is small.

start = {2008, 1, 1};
step = {{1, "Day"}, {5, "Week"}};
n = 50;

AbsoluteTiming[end = f[{start, Automatic, step}, n]]
(* {0.015600, {2012, 10, 30}} *)

DateRange[start, end, step] // Length
(* 50 *)

However, when n is large, this is terribly slow.

n = 10000;

AbsoluteTiming[end = f[{start, Automatic, step}, n]]
(* {5.148009, {2993, 7, 19}} *)

Is there a significantly faster way to compute the date end?

  • $\begingroup$ How does this compare to V8 timing? As per my comment in chat these functions were very slow previously. Michael Stern made some timing comparison with Excel/VBA and found VBA to be 80 times faster! Was hoping for significant speed up in 9. $\endgroup$ – Mike Honeychurch Dec 6 '12 at 22:17
  • $\begingroup$ @MikeHoneychurch even my slow method was about 4X faster in M9. It took 22.18 seconds in 8.0.4 vs the 5.15 seconds in 9.0.0. Your solution is also about 4 to 5X faster in 9. $\endgroup$ – Andy Ross Dec 6 '12 at 23:02
  • $\begingroup$ 4X is better than 1X but was hoping for much greater improvement in 9 (given the timing comparison with V8 and Excel) $\endgroup$ – Mike Honeychurch Dec 6 '12 at 23:28

There isn't much in it but here's a faster solution. Given

dt = {{1, "Day"}, {5, "Week"}};
n = 10000;
start = {2008, 1, 1};

You could do

(absDt = DatePlus[0, dt];
  future = AbsoluteTime[start] + (n - 1)*absDt;
  DateList[future]) // AbsoluteTiming

Executes in 0.003 seconds on my machine. Leonid's solution takes a little longer:

DatePlus[start, {{DateDifference[start, DatePlus[start, dt]]*(n - 1), 
    "Day"}}] // AbsoluteTiming

Executes in 0.007 seconds on my machine.

  • 1
    $\begingroup$ Good stuff, +1. $\endgroup$ – Leonid Shifrin Dec 6 '12 at 17:50
  • $\begingroup$ I was halfway through typing this answer and saw that you had got in first so I desperately cast around for a reason to have my solution up here too. As good fortune had it, I managed to shave off a few thousands of a second. Was luck though :) $\endgroup$ – WalkingRandomly Dec 6 '12 at 18:00
  • $\begingroup$ Yeah, this fastest gun in the West is really a problem. I view it as one of the shortcomings for the SE model, which promotes competition far more than collaboration. OTOH, it is not obvious to me whether or not the decrease of degree of competition would be better, since lots of folks appreciate this element of RPG, making it more fun to answer. $\endgroup$ – Leonid Shifrin Dec 6 '12 at 18:06
  • 1
    $\begingroup$ At the end at the end of the day,the point of this site is to provide people with help about Mathematica. sure it can be frustrating to be beaten to an answer but the OP has been helped in record time and that's What matters. Rep matters when you don't have much but once you have a reasonable amount you don't worry so much. $\endgroup$ – WalkingRandomly Dec 6 '12 at 18:42
  • $\begingroup$ I agree. While there are some problems with the SE model, nothing is perfect, and it most definitely works, and works pretty well. $\endgroup$ – Leonid Shifrin Dec 6 '12 at 18:50

Perhaps, this could be a start:

DatePlus[start, {{DateDifference[start, DatePlus[start, dt]]*(n - 1), "Day"}}]
  • $\begingroup$ Exactly the type of thing I was hoping for. I was getting stuck in how to "multiply" the step by (n-1). $\endgroup$ – Andy Ross Dec 6 '12 at 16:53
  • $\begingroup$ @AndyRoss Well, great then! $\endgroup$ – Leonid Shifrin Dec 6 '12 at 16:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.