как установить время существующего NSDate? - PullRequest
24 голосов
/ 19 марта 2011

Как мне установить существующее время NSDate?

То есть у меня есть дата (скажем, текущая дата / время), но затем я хочу установить ее на определенное время (например, 11.23 утра).) сказать.Какой самый быстрый способ сделать это в задаче C?

Я смотрю на NSCalendar и вижу такие методы, как dateByAddingComponents:toDate:options: и dateFromComponents:, но они, похоже, не совсем ударили поОтметьте, что мне нужно здесь.Например:

  1. dateFromComponents: - мне пришлось бы отработать все компоненты, чтобы это работало, что выглядит как перебор
  2. dateByAddingComponents:toDate:options: - Я не хочу добавлять вмой случай, а скорее "установить" время.

Ответы [ 6 ]

70 голосов
/ 19 марта 2011
NSDate *date = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents *components = [gregorian components: NSUIntegerMax fromDate: date];
[components setHour: 7];
[components setMinute: 59];
[components setSecond: 17];

NSDate *newDate = [gregorian dateFromComponents: components];

Я использую NSUIntegerMax вместо определенных битовых масок, объединенных по ИЛИ, потому что это проще, но если вы хотите указать, какие компоненты данных получать, будьте моим гостем.

11 голосов
/ 17 октября 2013

iOS 7 Примечание: Я задаю это в нескольких из этих вопросов, потому что использование NSUIntegerMax, кажется, больше не работает на iOS7, и использование его заставило меня преследовать мой хвост в течение приблизительно 3 часов.Я только что обнаружил, что когда я использую NSUIntegerMax, NSDateComponents игнорирует установленный год.Так, например, это НЕ меняет год:

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [gregorian components:NSUIntegerMax fromDate:date];
[comps setYear:year];
return [gregorian dateFromComponents:comps];

Принимая во внимание, что это ДЕЛАЕТ:

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger timeComps = (NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSTimeZoneCalendarUnit);
NSDateComponents *comps = [gregorian components:timeComps fromDate:date];
[comps setYear:year];
return [gregorian dateFromComponents:comps];

Это может быть ошибка iOS7, или может быть, что использование NSUIntegerMax было случайностью, котораябольше не работает.Я отправлю отчет об ошибке и получу окончательный ответ.

В любом случае, если вы хотите избежать непредвиденных последствий, укажите ВСЕ компоненты, иначе вы можете преследовать свой хвост!

8 голосов
/ 27 октября 2015

Swift 2.0 версия о том, как вы установите данную дату на 8 утра

extension NSDate {

func setTo8AM() -> NSDate {
    let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
    let components = calendar.components(([.Day, .Month, .Year]), fromDate: self)
    components.hour = 8
    return calendar.dateFromComponents(components)!
}

}
3 голосов
/ 17 марта 2016

Вот более общее расширение Swift (v2.1.1), основанное на полезном ответе Эндрю Шрайбера.

extension NSDate {
    func dateWithTime(hour: Int, minute: Int, second: Int) -> NSDate? {
        let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
        let components = calendar.components(([.Day, .Month, .Year]), fromDate: self)
        components.hour = hour
        components.minute = minute
        components.second = second
        let newDate = calendar.dateFromComponents(components)
        return newDate
    }
}
3 голосов
/ 06 июня 2012

Примените это, чтобы установить время от другой даты к существующей дате

NSDate *today = [NSDate date]; // from which i need only "Year" "Month" "Date"

NSCalendar *calendar = [NSCalendar currentCalendar]
NSDateComponents *dateComponents = [calendar components:( NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit ) fromDate:today];

NSDate *timeDate = datePicker.date; // from which i need only "Hours" "Minutes" and "Seconds"

NSDateComponents *timeComponents = [calendar components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:timeDate];

            [dateComponents setHour:[timeComponents hour]];
            [dateComponents setMinute:[timeComponents minute]];
            [dateComponents setSecond:[timeComponents second]];

NSDate *newDate = [calendar dateFromComponents:dateComponents]; // New Date with My "Year" "Month" "Date" "Hours" "Minutes" and "Seconds" 

            NSLog(@"New Date: %@",newDate);
1 голос
/ 08 февраля 2015

Быстрый пример.Для моих целей я хотел, чтобы завтра было около 12 часов дня.

var tomorrow:NSDate = NSDate().dateByAddingTimeInterval(60*60*24); //60seconds*60minutes*12hours
var gregorian:NSCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!;
var unit : NSCalendarUnit = (NSCalendarUnit.YearCalendarUnit|NSCalendarUnit.MonthCalendarUnit|NSCalendarUnit.DayCalendarUnit|NSCalendarUnit.HourCalendarUnit|NSCalendarUnit.MinuteCalendarUnit);
var comps:NSDateComponents = gregorian.components(unit, fromDate: tomorrow);
comps.setValue(12, forComponent: NSCalendarUnit.HourCalendarUnit);
comps.setValue(0, forComponent: NSCalendarUnit.MinuteCalendarUnit);
var noon_tomorrow : NSDate = gregorian.dateFromComponents(comps)!;
...