3
$\begingroup$

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?

$\endgroup$
3
  • $\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$ Dec 6, 2012 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, 2012 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$ Dec 6, 2012 at 23:28

2 Answers 2

5
$\begingroup$

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.

$\endgroup$
5
  • 1
    $\begingroup$ Good stuff, +1. $\endgroup$ Dec 6, 2012 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$ Dec 6, 2012 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$ Dec 6, 2012 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$ Dec 6, 2012 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$ Dec 6, 2012 at 18:50
5
$\begingroup$

Perhaps, this could be a start:

DatePlus[start, {{DateDifference[start, DatePlus[start, dt]]*(n - 1), "Day"}}]
$\endgroup$
2
  • $\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, 2012 at 16:53
  • $\begingroup$ @AndyRoss Well, great then! $\endgroup$ Dec 6, 2012 at 16:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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