views:

3729

answers:

6

How would I generate a random date that has to be between two other given dates? The functions signature should something like this-

randomDate("1/1/2008 1:30 PM", "1/1/2009 4:50 AM", 0.34)
                  ^                       ^          ^

           date generated has   date generated has  random number
           to be after this     to be before this

and would return a date such as- "2/4/2008 7:20 PM"

+12  A: 

Convert both strings to timestamps (in your chosen resolution, e.g. milliseconds, seconds, hours, days, whatever), subtract the earlier from the later, multiply your random number (assuming it is distributed in the range [0, 1]) with that difference, and add again to the earlier one. Convert the timestamp back to date string and you have a random time in that range.

Python example (output is almost in the format you specified, other than 0 padding - blame the American time format conventions):

import random
import time

def strTimeProp(start, end, format, prop):
    """Get a time at a proportion of a range of two formatted times.

    start and end should be strings specifying times formated in the
    given format (strftime-style), giving an interval [start, end].
    prop specifies how a proportion of the interval to be taken after
    start.  The returned time will be in the specified format.
    """

    stime = time.mktime(time.strptime(start, format))
    etime = time.mktime(time.strptime(end, format))

    ptime = stime + prop * (etime - stime)

    return time.strftime(format, time.localtime(ptime))


def randomDate(start, end, prop):
    return strTimeProp(start, end, '%m/%d/%Y %I:%M %p', prop)

print randomDate("1/1/2008 1:30 PM", "1/1/2009 4:50 AM", random.random())
Tom Alsberg
+1  A: 
  1. Convert your input dates to numbers (int, float, whatever is best for your usage)
  2. Choose a number between your two date numbers.
  3. Convert this number back to a date.

Many algorithms for converting date to and from numbers are already available in many operating systems.

mouviciel
A: 

What do you need the random number for? Usually (depending on the language) you can get the number of seconds/milliseconds from the Epoch from a date. So for a randomd date between startDate and endDate you could do:

  1. compute the time in ms between startDate and endDate (endDate.toMilliseconds() - startDate.toMilliseconds())
  2. generate a number between 0 and the number you obtained in 1
  3. generate a new Date with time offset = startDate.toMilliseconds() + number obtained in 2
tehvan
A: 

Conceptually it's quite simple. Depending on which language you're using you will be able to convert those dates into some reference 32 or 64 bit integer, typically representing seconds since epoch (1 January 1970) otherwise known as "Unix time" or milliseconds since some other arbitrary date. Simply generate a random 32 or 64 bit integer between those two values. This should be a one liner in any language.

On some platforms you can generate a time as a double (date is the integer part, time is the fractional part is one implementation). The same principle applies except you're dealing with single or double precision floating point numbers ("floats" or "doubles" in C, Java and other languages). Subtract the difference, multiply by random number (0 <= r <= 1), add to start time and done.

cletus
+6  A: 

The easiest way of doing this is to convert both numbers to timestamps, then set these as the minimum and maximum bounds on a random number generator.

A quick PHP example would be:

// Find a randomDate between $start_date and $end_date
function randomDate($start_date, $end_date)
{
    // Convert to timetamps
    $min = strtotime($start_date);
    $max = strtotime($end_date);

    // Generate random number using above bounds
    $val = rand($min, $max);

    // Convert back to desired date format
    return date('Y-m-d H:i:s', $val);
}

This function makes use of strtotime() to convert a datetime description into a Unix timestamp, and date() to make a valid date out of the random timestamp which has been generated.

ConroyP
If anyone can write that in python that would be helpful.
quilby
+15  A: 
from random import randrange
from datetime import timedelta, datetime

def random_date(start, end):
    """
    This function will return a random datetime between two datetime 
    objects.
    """
    delta = end - start
    int_delta = (delta.days * 24 * 60 * 60) + delta.seconds
    random_second = randrange(int_delta)
    return (start + timedelta(seconds=random_second))

The precision is seconds. You can increase precision up to microseconds, or decrease to, say, half-hours, if you want. For that just change the last lines calculation.

example run:

d1 = datetime.strptime('1/1/2008 1:30 PM', '%m/%d/%Y %I:%M %p')
d2 = datetime.strptime('1/1/2009 4:50 AM', '%m/%d/%Y %I:%M %p')

print random_date(d1, d2)

output:

2008-12-04 01:50:17
nosklo
I'm fairly certain this code has a bug -- the return statement should use the "end" variable, not the "start".
Huuuze
@Huuuze: huh, have you tried it? Why do you think that?
nosklo