16698
目標としては、取得した日付に対して時間情報を付け加えて、LocalNotificationにセットし  
隔週の指定時間に鳴らす。ということを目指しています。

以下のようなコードで指定した曜日を取得しています。

```

    - (NSDate *) getDateOfSpecificDay:(NSInteger ) day 
    {
        //sunday = 1,monday = 2,...
        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;
        NSDateComponents *daysComponents = [[NSDateComponents alloc] init];
        daysComponents.day = differenceDays;
        NSDate *resultDate = [[NSCalendar currentCalendar] dateByAddingComponents:daysComponents toDate:[NSDate date] options:0];
        NSLog(@"result:%@",resultDate);
        return resultDate;
    }
    
```

ここに時間情報を加えようと思い、以下のように書き換えてみました。

```

    - (NSDate *) getDateOfSpecificDay:(NSInteger ) day hour:(NSInteger)hour minutes:(NSInteger)minutes
    {
        //sunday = 1,monday = 2,...
        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;
        NSDateComponents *daysComponents = [[NSDateComponents alloc] init];
        daysComponents.day = differenceDays;
        //add 時
        daysComponents.hour = hour;
        //add 分
        dateComponents.minute = minutes;
        NSDate *resultDate = [[NSCalendar currentCalendar] dateByAddingComponents:daysComponents toDate:[NSDate date] options:0];
        NSLog(@"result:%@",resultDate);
        return resultDate;
    }
    
```

しかしビルドしても[指定日付,現在時,現在分]でNSDateが帰ってきてしまいます。

原因としては  
・dateComponentsやresultDateで[NSDate date]を使ってしまっている  
というのではないかと思っているのですが、解決へのアプローチが分かりません。

この改善策を教えて頂けないでしょうか?
CC BY-SA 3.0
2015-09-16T09:48:50.480
16688
2015-09-16T12:32:04.613
8320
question
ios objective-c
[obj-c]NSDateで指定曜日の指定時間を取得する
時間、分を指定してNSDateを作りたいならばNSCalendarの以下のメソッドで実現できます。

```

    - (NSDate *)dateBySettingHour:(NSInteger)h minute:(NSInteger)m second:(NSInteger)s ofDate:(NSDate *)date options:(NSCalendarOptions)opts
    
```

日付・時間を扱う場合、それがGMTなのかローカル時間なのか意識してください。

日本の場合、GMTと9時間の差があるため、見込んだ結果と9時間ズレたりしがちです。

ざっくりとした実装ですが、以下が参考になれば幸いです。

```

    - (NSDate *) getDateOfSpecificDay:(NSInteger ) day hour:(NSInteger)hour minutes:(NSInteger)minutes
    {
        //sunday = 1,monday = 2,...
        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;
        NSDateComponents *daysComponents = [[NSDateComponents alloc] init];
        daysComponents.day = differenceDays;
        NSDate *resultDate = [[NSCalendar currentCalendar] dateByAddingComponents:daysComponents toDate:[NSDate date] options:0];
        NSLog(@"result 1:%@",resultDate);
    
        // ■ hour, minutesを設定した場合(日本の場合GMTとの時差9時間)
        NSDate *resultDateWithTime = [[NSCalendar currentCalendar] dateBySettingHour:13 minute:minutes second:0 ofDate:resultDate options:NSCalendarMatchStrictly];
        NSLog(@"result 2:%@",resultDateWithTime);
    
        // ■ TimeZone指定をした場合
        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSDateComponents *comps = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:resultDate];
        NSDateComponents *new_comps = [[NSDateComponents alloc] init];
        [new_comps setYear:comps.year];
        [new_comps setMonth:comps.month];
        [new_comps setDay:comps.day];
        [new_comps setHour:hour];
        [new_comps setMinute:minutes];
        [new_comps setSecond:0];
        NSDate *tmp = [calendar dateFromComponents:new_comps];
        NSTimeZone *tz = [NSTimeZone systemTimeZone];
        NSInteger seconds = [tz secondsFromGMTForDate:tmp];
        NSDate *local_date = [tmp dateByAddingTimeInterval:seconds];
        NSLog(@"result 3:%@", local_date);
    
        return local_date;
    }
    
```
CC BY-SA 3.0
2015-09-16T12:32:04.613
16698
2015-09-16T12:32:04.613
11109
16688
answer