2012-04-10 91 views
9

我想在兩個日期之間生成一個隨機日期 - 例如今天到現在60天之間的隨機日期。我怎麼做?如何在objective-c中生成一個隨機日期?

UPDATE

運用的答案信息,我想出了這個方法,這是我經常使用:

// 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; 
} 
+0

[最簡單的方法來在iPhone上的兩個NSDates之間循環?](http://stackoverflow.com/questions/3357257/simplest-way-to-loop-between-two-nsdates-on-iphone) – 2012-04-10 17:49:03

+0

我不知道你在想什麼@luliusCæsar,但這個問題甚至沒有模糊地類似於兩個日期之間的循環... – memmons 2012-04-11 16:24:13

+0

相同的代碼,重構和記錄https://gist.github.com/eirnym/c9526a045556e4d8464b41a367843e3c – 2016-04-26 13:39:39

回答

9
  1. 產生一個隨機數1到60之間

    int r = arc4random_uniform(60) + 1; 
    
    // Usage : arc4random_uniform(hi - lo + 1) + lo 
    
  2. 獲取當前da TE

    [NSDate date]; 
    
  3. 使用NSDateComponents從您的days組件減去隨機數併產生一個新的日期。

+3

儘管這裏可能不是什麼大事,但使用%幾乎總是偏向隨機數。你想要的功能是arc4random_uniform()。 – 2012-04-10 16:30:27

+0

@RobNapier是的,我同意。與'_uniform'的交易是什麼? – Legolas 2012-04-10 17:12:08

+4

arc4random_uniform(upper_bound)僅返回大於或等於0且小於upper_bound的整數,以使分佈均勻。也就是說,範圍內的所有值都是相同的可能性。 – 2012-04-10 17:51:54

17

獲取一個隨機數並將其用作時間間隔,然後將其添加到開始日期。例如。

NSTimeInterval timeBetweenDates = [endDate timeIntervalSinceDate:startDate]; 
NSTimeInterval randomInterval = ((NSTimeInterval)arc4random()/ARC4RANDOM_MAX) * timeBetweenDates; 

NSDate *randomDate = [startDate dateByAddingTimeInterval:randomInterval]; 
+3

如果你得到關於ARC4RANDOM_MAX的錯誤,用0x100000000代替它,或者使用#define ARC4RANDOM_MAX 0x100000000 – budidino 2014-08-18 23:38:45

+1

順便說一句,我認爲這應該是被接受的答案,因爲它解決了比接受的答案更多的隨機日期用例。 – budidino 2014-08-19 00:11:09

2

使用秒。僞代碼:

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 
+1

由於夏令時的啓動和停止,天可能長於或短於24小時。 – 2012-04-11 07:08:08

+1

啊,是的,這是正確的。此方法將在60天內+/- 1小時內產生一個隨機數據,這在大多數情況下是可以接受的。 – 2012-04-11 09:26:24

5

這裏框架在生成隨機日期方面做得很好。但是在斯威夫特: https://github.com/thellimist/SwiftRandom/blob/master/SwiftRandom/Randoms.swift

public extension NSDate { 
    /// SwiftRandom extension 
    public static func randomWithinDaysBeforeToday(days: Int) -> NSDate { 
     let today = NSDate() 

     guard let gregorian = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian) else { 
      print("no calendar \"NSCalendarIdentifierGregorian\" found") 
      return today 
     } 

     let r1 = arc4random_uniform(UInt32(days)) 
     let r2 = arc4random_uniform(UInt32(23)) 
     let r3 = arc4random_uniform(UInt32(23)) 
     let r4 = arc4random_uniform(UInt32(23)) 

     let offsetComponents = NSDateComponents() 
     offsetComponents.day = Int(r1) * -1 
     offsetComponents.hour = Int(r2) 
     offsetComponents.minute = Int(r3) 
     offsetComponents.second = Int(r4) 

     guard let rndDate1 = gregorian.dateByAddingComponents(offsetComponents, toDate: today, options: []) else { 
      print("randoming failed") 
      return today 
     } 
     return rndDate1 
    } 

    /// SwiftRandom extension 
    public static func random() -> NSDate { 
     let randomTime = NSTimeInterval(arc4random_uniform(UInt32.max)) 
     return NSDate(timeIntervalSince1970: randomTime) 
    } 

} 
+0

不錯的延伸! r3和r4隨機數不應隨機分配至59? – 2016-05-20 20:50:36

+0

嗯,是啊:D隨時發送github上的拉請求 – Esqarrouth 2016-05-20 21:05:01

+0

好的,拉請求發送。順便說一句,SwiftRandom是sooooooo有用,感謝您的建議!你是作者嗎? – 2016-05-20 22:56:55

0

斯威夫特3.X +

public extension Date { 
    /// SwiftRandom extension 
    public static func randomWithinDaysBeforeToday(days: Int) -> Date { 
     let today = Date() 
     let gregorian = Calendar(identifier: .gregorian) 

     let r1 = arc4random_uniform(UInt32(days)) 
     let r2 = arc4random_uniform(UInt32(23)) 
     let r3 = arc4random_uniform(UInt32(23)) 
     let r4 = arc4random_uniform(UInt32(23)) 

     let offsetComponents = NSDateComponents() 
     offsetComponents.day = Int(r1) * -1 
     offsetComponents.hour = Int(r2) 
     offsetComponents.minute = Int(r3) 
     offsetComponents.second = Int(r4) 

     let rndDate1 = gregorian.date(byAdding: offsetComponents as DateComponents, to: today) 
     return rndDate1! 
    } 

    /// SwiftRandom extension 
    public static func random() -> Date { 
     let randomTime = TimeInterval(arc4random_uniform(UInt32.max)) 
     return Date(timeIntervalSince1970: randomTime) 
    } 
} 

附: Esqarrouthanswer更正了最新的Swift。