Repeat UILocalNotification on Specific day

后端 未结 5 1490
滥情空心
滥情空心 2021-02-03 14:30

I need to set UILocalNotification, I just need to take hour and minute from DatePicker and need to set specific date ( like : Monday ) and repeat it on every Monday.

相关标签:
5条回答
  • 2021-02-03 14:43

    Here is the swift version:

    func calculateTheNExtFriday(inputTime: NSDate) -> NSDate {
        let desiredWeekday = 6 // Friday
    
        let weekDateRange = NSCalendar.currentCalendar().maximumRangeOfUnit(NSCalendarUnit.Weekday)
        let daysInWeek = weekDateRange.length - weekDateRange.location + 1;
    
        let currentWeekday = NSCalendar.currentCalendar().components(NSCalendarUnit.Weekday, fromDate: inputTime).weekday
        let differenceDays = (desiredWeekday - currentWeekday + daysInWeek) % daysInWeek
    
        let dateComponents = NSDateComponents()
        dateComponents.day = differenceDays
    
        let calculatedFridayDate = NSCalendar.currentCalendar().dateByAddingComponents(dateComponents, toDate: inputTime, options: NSCalendarOptions.init(rawValue: 0))
        return calculatedFridayDate!
    }
    

    In this example, I use the desiredWeekday inside the function but you can use it as parameter as well.

    NB: Keep in mind that the day 1 corresponds to Sunday, 2 -> Monday and so on

    0 讨论(0)
  • 2021-02-03 14:46

    Question 1 => I can not understand what you want. (But if you want to display only name of days such like sunday, monday,....to saturday then use UIPickerView.)

    Question 2 => YES you can get correct date of specific day and you can get notification on every specific day by set localNotification.repeatInterval = NSWeekCalendarUnit;

    For achieve it, also need to use following piece of (method's) code. This method will return correct date of specific selected day, you just need to pass day as parameter of method such like,

    If selected day is sunday then pass 1
    If selected day is monday then pass 2
    .
    .
    .
    If selected day is saturday then pass 7

    Here is method code :

    -(NSDate *) getDateOfSpecificDay:(NSInteger ) day /// here day will be 1 or 2.. or 7
    {
      NSInteger desiredWeekday = day
      NSRange weekDateRange = [[NSCalendar currentCalendar] maximumRangeOfUnit:NSWeekdayCalendarUnit];
      NSInteger daysInWeek = weekDateRange.length - weekDateRange.location + 1;
    
      NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:[NSDate date]];
      NSInteger currentWeekday = dateComponents.weekday;
      NSInteger differenceDays = (desiredWeekday - currentWeekday + daysInWeek) % daysInWeek;
      NSDateComponents *daysComponents = [[NSDateComponents alloc] init];
      daysComponents.day = differenceDays;
      NSDate *resultDate = [[NSCalendar currentCalendar] dateByAddingComponents:daysComponents toDate:[NSDate date] options:0];
      return resultDate;
    }
    

    And don't forget to set localNotification.repeatInterval = NSWeekCalendarUnit;

    0 讨论(0)
  • Here's @iPatel's solution that also factors in the time component passed in via the datepicker. (I also updated his solution to use the latest calendar units that aren't deprecated).

    - (NSDate *) getFireDateForDayOfWeek:(NSInteger)desiredWeekday withTime:(NSDate *)time // 1:Sunday - 7:Saturday
    {
        NSRange weekDateRange = [[NSCalendar currentCalendar] maximumRangeOfUnit:NSCalendarUnitWeekday];
        NSInteger daysInWeek = weekDateRange.length - weekDateRange.location + 1;
    
        NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSCalendarUnitWeekday fromDate:[NSDate date]];
        NSInteger currentWeekday = dateComponents.weekday;
        NSInteger differenceDays = (desiredWeekday - currentWeekday + daysInWeek) % daysInWeek;
    
        NSDateComponents *daysComponents = [[NSDateComponents alloc] init];
        daysComponents.day = differenceDays;
        NSDate *fireDate = [[NSCalendar currentCalendar] dateByAddingComponents:daysComponents toDate:[NSDate date] options:0];
    
        NSDateComponents *timeComponents = [[NSCalendar currentCalendar] components:     NSCalendarUnitHour | NSCalendarUnitMinute fromDate:time];
        NSDateComponents *fireDateComponents = [[NSCalendar currentCalendar]
                    components: NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond
                    fromDate:fireDate];
    
        fireDateComponents.hour = timeComponents.hour;
        fireDateComponents.minute = timeComponents.minute;
        fireDateComponents.second = 0;
    
        NSDate *resultDate = [[NSCalendar currentCalendar] dateFromComponents:fireDateComponents];
    
        // The day could be today but time is in past. If so, move ahead to next week
        if(resultDate.timeIntervalSinceNow < 0) {
            resultDate = [resultDate dateByAddingTimeInterval:60 * 60 * 24 * 7];
        }
    
        return resultDate;
    }
    
    0 讨论(0)
  • 2021-02-03 14:59

    This solution also takes time in account but it's a bit more simplified than Oren's

    -(NSDate *) dateOfSpecificDay:(NSInteger ) day withFireTime:(NSDate *)timeDate/// here day will be 1 or 2.. or 7 and timeDate the current day with the desired time 
    {
        NSInteger desiredWeekday = day;
        NSRange weekDateRange = [[NSCalendar currentCalendar] maximumRangeOfUnit:NSCalendarUnitWeekday];
        NSInteger daysInWeek = weekDateRange.length - weekDateRange.location + 1;
    
        NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSCalendarUnitWeekday fromDate:[NSDate date]];
        NSInteger currentWeekday = dateComponents.weekday;
        NSInteger differenceDays = (desiredWeekday - currentWeekday + daysInWeek) % daysInWeek;
        if (differenceDays == 0) {
            //Check if should register for same day or for next week
            if ([timeDate compare:[NSDate date]] == NSOrderedAscending) {
                //Should schedule for next week
                differenceDays = daysInWeek;
            }
        }
    
        NSDateComponents *daysComponents = [[NSDateComponents alloc] init];
        daysComponents.day = differenceDays;
        NSDate *resultDate = [[NSCalendar currentCalendar] dateByAddingComponents:daysComponents toDate:timeDate options:0];
    
        return resultDate;
    }
    
    0 讨论(0)
  • 2021-02-03 15:04

    Swift 3:

    func calculateSpecificDay(_ desiredWeekday: NSInteger, fromDate: Date = Date()) -> Date {
    
        let weekDateRange = NSCalendar.current.maximumRange(of: .weekday)!
        let daysInWeek = weekDateRange.lowerBound.distance(to: weekDateRange.upperBound) - weekDateRange.lowerBound + 1
    
        let currentWeekday = NSCalendar.current.dateComponents([.weekday], from: fromDate).weekday
        let differenceDays = (desiredWeekday - currentWeekday! + daysInWeek) % daysInWeek
    
        var dateComponents = DateComponents()
        dateComponents.day = differenceDays
    
        let calculatedFridayDate = NSCalendar.current.date(byAdding: dateComponents, to: fromDate)
        return calculatedFridayDate!
    }
    
    If selected day is sunday then pass 1
    If selected day is monday then pass 2
    .
    .
    .
    If selected day is saturday then pass 7
    
    0 讨论(0)
提交回复
热议问题