Как мне установить существующее время NSDATE?
-
27-10-2019 - |
Вопрос
Как мне установить существующее NSDate
Время?
То есть у меня есть дата (скажем, текущая дата/время), но тогда я хочу установить это на определенное время (например, 11.23 утра). Как самый быстрый способ сделать это в объективном C?
Я смотрю NSCalendar
и увидеть такие методы, как dateByAddingComponents:toDate:options:
, а также dateFromComponents:
, но они, похоже, не достигли цели за то, что мне нужно здесь. Например:
dateFromComponents:
- Мне пришлось бы выработать все компоненты для работы, что кажется излишнимdateByAddingComponents:toDate:options:
- Я не хочу добавлять в своем случае, а скорее «установить» время.
Решение
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
Вместо конкретных или объединенных битовых масок, потому что это проще, но если вы хотите указать, какие компоненты данных получить, будьте моим гостем.
Другие советы
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 - это случайность, которая больше не работает. Я подам отчет об ошибке и получу окончательный ответ.
Несмотря на это, если вы хотите избежать неожиданных последствий, укажите все компоненты, иначе вы можете преследовать свой хвост!
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)!
}
}
Примените это, чтобы установить время от другой даты до существующей даты
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);
Вот более общее расширение 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
}
}
Быстрый пример. Для моих целей я хотел получить свидание около 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)!;