views:

162

answers:

3

I have a requirement that goes as follows (trust me, I'm way too old for homework grin)

I have a bunch of tasks that run with various frequencies. They also have a start "seed" date/time . The start seed is sometime in the past, could be one minute ago, could be 5 years ago.

I need to calculate the next run time for the task, using the start seed date/time and the frequency - it cannot simply be "now" + the task frequency (for those of you who have scheduled jobs on MS SQL Server this is a familiar concept)

Now the silly way to do it is to take the start seed and keep adding the frequency until it becomes greater than "now". That's hardly optimal. The naive way to do it would be to take the start seed date, change it to today's date and leave the time as is, then add the frequency until it's greater than now, but that assumes the frequency is a multiple of 24 hours.

So what's the best/quickest way to do this? Bonus points for a C# solution, but this is generic enough to make an interesting puzzle for any language :)

+4  A: 

A better method would be to take the difference between the start timestamp and the current timestamp, divide that by the frequency, round the resulting multiplier up to the nearest integer, multiply by the frequency again, and add that to the start timestamp once more.

The act of rounding up will provide the proper offset.

Amber
A: 

Your answer would essentially be this:

next_time = ceiling((now - seed)/frequency) * frequency + seed

Using the ceiling function ensures that next_time will be >= now.

You would have to do the necessary conversions to be able to perform this arithmetic on the dates (e.g., translate to UNIX time, which is number of seconds since Jan 1, 1970.)

I am not familiar with C# so I can't offer the code, but I assume that C# has date/time utility classes for dealing with date/time arithmetic operations.

alanlcode
You've got an extra right paren after frequency.
John Y
Thanks, fixed it.
alanlcode
A: 

Interesting puzzle, thanks for the challenge :)

This should do it in c#. Could almost certainly be slimmed down, but its verbose enough to explain whats going on.

// Initialise with date the event started, and frequency
DateTime startDate = new DateTime(2009, 8,1,9,0,0);
TimeSpan frequency = new TimeSpan(0, 15, 0);

// Store datetime now (so that it doesnt alter during following calculations)
DateTime now = DateTime.Now;

// Calculate the number of ticks that have occured since the event started
TimeSpan pastTimeSpan = now.Subtract(startDate);

// Divide the period that the event has been running by the frequency
// Take the remaining time span
TimeSpan remainingTimeSpan = new TimeSpan(pastTimeSpan.Ticks % frequency.Ticks);

// Calculate last occurence the event ran
DateTime lastOccurence = now.Subtract(remainingTimeSpan);

// Calculate next occurence the event will run
DateTime nextOccurence = lastOccurence.Add(frequency);
PaulG