0

Here's an example of what I want. The user may set up an alarm in my app for 1 minute in the future, so they can test it out. The time might be 19:23, so they'll set the alarm to 19:24, in which case I want it to be triggered on the next occurrence of 19:24 - in 1 minute's time.

If they set the alarm for 8am, I don't want it to set to 8am on the current day, but on the next occurrence of 8am - on following day.

How can I get it to aim for the next occurrence of the time chosen?

Andrew
  • 15,935
  • 28
  • 121
  • 203

3 Answers3

1

Assuming that the alarm time is given as "hour" and "minute", the following code should produce the desired result:

NSDate *now = [NSDate date];
// Example values for testing:
NSUInteger alarmHour = 10;
NSUInteger alarmMinute = 5;

// Compute alarm time by replacing hour/minute of the current time
// with the given values:
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *comp = [cal components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit
                                fromDate:now];
[comp setHour:alarmHour];
[comp setMinute:alarmMinute];
NSDate *alarm = [cal dateFromComponents:comp];

// If alarm <= now ...
if ([alarm compare:now] != NSOrderedDescending) {
    // ... add one day:
    NSDateComponents *oneDay = [[NSDateComponents alloc] init];
    [oneDay setDay:1];
    alarm = [cal dateByAddingComponents:oneDay toDate:alarm options:0];
}
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
0

More tersely, what @HotLicks suggests:

NSDate *userEnteredDate;
NSDate *now = [NSDate date];

if (now == [now laterDate:userEnteredDate]) {
    NSDateComponents *components = [[NSCalendar currentCalendar] components:255 fromDate:userEnteredDate];  // 255= the important component masks or'd together
    components.day += 1;
    userEnteredDate = [[NSCalendar currentCalendar] dateFromComponents:components];
}
danh
  • 62,181
  • 10
  • 95
  • 136
-3
    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
    NSDateFormatter *formatter_ = [[NSDateFormatter alloc]init];

    NSDate *alarmDate = [formatter dateFromString:@"enter your users alarm time-examle(2345)"];
    NSDate *currentDate = [NSDate date];

     [formatter setDateFormat:@"HHmm"];

    NSDate *finalDate;

    if ([[formatter stringFromDate:currentDate] intValue] > [[formatter stringFromDate:alarmDate] intValue]) {
        [formatter setDateFormat:@"HH:mm"];

        [formatter_ setDateFormat:@"dd MM yyyy"];


        NSDate *date = [currentDate dateByAddingTimeInterval:60*60*24*1];

        finalDate = [formatter_ dateFromString:[NSString stringWithFormat:@"%@ %@",[formatter stringFromDate:alarmDate],[formatter_ stringFromDate:date]]];
    }else{

        finalDate = [formatter_ dateFromString:[NSString stringWithFormat:@"%@ %@",[formatter stringFromDate:alarmDate],[formatter_ stringFromDate:currentDate]]];
    }
Metin Say
  • 435
  • 1
  • 4
  • 13
  • 5
    Remarks: 1) NSDate has a `compare:` method. There is no need to convert NSDate -> NSString -> int just to compare two dates. - 2) **A day does not always have 86400 seconds.** The proper method to add a day is `dateByAddingComponents:...`. – Martin R Sep 04 '13 at 18:54
  • 1
    Adding 60*60*24 is not a good practice. It is better to use NSDateComponents and add 1 day. Reason explained in Apple documentation (leap seconds, etc.) – Juan Catalan Sep 04 '13 at 18:56
  • +1 Martin R, it is better to always use the API and as Apple says in its documentation don't make assumptions on a day having 86400 seconds. – Juan Catalan Sep 04 '13 at 19:01
  • It is funny that an answer as this http://stackoverflow.com/questions/5067785/how-do-i-add-1-day-to-a-nsdate get 37+ and mine gets 3- for the same thing. – Metin Say Sep 04 '13 at 19:09
  • @MetinSay: That answer has 66 upvotes and 29 downvotes, and some people have commented that it is not the correct solution. (The problem are the daylight savings time transitions, where one day can have 23 or 25 hours.) – Martin R Sep 04 '13 at 19:11
  • Sorry I didn't know. My bad! Guess I need to go and study some geography. – Metin Say Sep 04 '13 at 19:15
  • No, boy, no need for that. It is explained in the first page of one of the Apple documents. Just read the docs. – Juan Catalan Sep 04 '13 at 19:21
  • @JuanCatalan: I am not an expert on that topic, but I think that leap seconds are *not* a problem. As far as I know, the unix time increases by 86400 on a "normal" day, regardless of leap seconds. - But that is a different topic. – Martin R Sep 04 '13 at 19:23
  • Ok I was just kidding; but thanx for the suggestion. – Metin Say Sep 04 '13 at 19:23
  • @MartinR you're right, the main issue to use NSDateComponents is to correctly account for changes in the time zone offset due to daylight savings time or other changes due to political reasons. – Juan Catalan Sep 04 '13 at 19:39