Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you generate a random date in objective-c?

I'd like to generate a random date between two dates -- for example a random date between today and 60 days from now. How do I do that?

UPDATE

Using information from the answers, I came up with this method, which I use quite often:

// Generate a random date sometime between now and n days before day.
// Also, generate a random time to go with the day while we are at it.
- (NSDate *) generateRandomDateWithinDaysBeforeToday:(NSInteger)days
{
    int r1 = arc4random_uniform(days);
    int r2 = arc4random_uniform(23);
    int r3 = arc4random_uniform(59);

    NSDate *today = [NSDate new];
    NSCalendar *gregorian = 
             [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

    NSDateComponents *offsetComponents = [NSDateComponents new];
    [offsetComponents setDay:(r1*-1)];
    [offsetComponents setHour:r2];
    [offsetComponents setMinute:r3];

    NSDate *rndDate1 = [gregorian dateByAddingComponents:offsetComponents 
                                                  toDate:today options:0];

    return rndDate1;
}
like image 481
memmons Avatar asked Apr 10 '12 16:04

memmons


2 Answers

This is a Swift 4.x extension that will allow you to specify a period of days, which it will then use to find a random Date before or after the current date.

extension Date {
    static func randomDate(range: Int) -> Date {
        // Get the interval for the current date
        let interval =  Date().timeIntervalSince1970
        // There are 86,400 milliseconds in a day (ignoring leap dates)
        // Multiply the 86,400 milliseconds against the valid range of days
        let intervalRange = Double(86_400 * range)
        // Select a random point within the interval range
        let random = Double(arc4random_uniform(UInt32(intervalRange)) + 1)
        // Since this can either be in the past or future, we shift the range
        // so that the halfway point is the present
        let newInterval = interval + (random - (intervalRange / 2.0))
        // Initialize a date value with our newly created interval
        return Date(timeIntervalSince1970: newInterval)
    }
}

You call it like this:

Date.randomDate(range: 500) // Any date that is +/- 500 days from the current date

Running this 10 times produces:

2019-03-15 01:45:52 +0000
2018-12-20 02:09:51 +0000
2018-06-28 10:28:31 +0000
2018-08-02 08:13:01 +0000
2019-01-25 07:04:18 +0000
2018-08-30 22:37:52 +0000
2018-10-05 19:38:22 +0000
2018-11-30 04:51:18 +0000
2019-03-24 07:27:39 +0000
like image 83
CodeBender Avatar answered Oct 08 '22 14:10

CodeBender


Use seconds. Pseudocode:

1 Generate a random integer between 0 and (60 * 60 * 24 * 60)
2 Get the unixtime in seconds for the current time
3 Add your random integer
4 Convert this integer back to a date
like image 28
Albert Veli Avatar answered Oct 08 '22 13:10

Albert Veli