2011-09-02 66 views
7

我想我需要的时间设定的NSDate时间:分:秒 目前即时通讯与NSDate的组件工作,但它没有给出期望的结果如何在NSDate上设置时间?

[comps setHour: -hours]; 
[comps setMinute:0]; 
[comps setSecond:0]; 
NSDate *minDate = [calendar_c dateFromComponents:comps]; 
+0

NSDate的设计来表示时间真正的约会。你是否想设置实际日期的时间组件? –

回答

16

你的做法应该很好地工作。我需要针对此类型问题(设置各个日期组件)的解决方案,以下代码对我来说按预期工作。我的情况:我想创建一个使用当前日期的日期对象,但将时间设置为以字符串形式传入的值。

NSString *string = @"7:00"; 
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; 
NSDateFormatter *timeOnlyFormatter = [[NSDateFormatter alloc] init]; 
[timeOnlyFormatter setLocale:locale]; 
[timeOnlyFormatter setDateFormat:@"h:mm"]; 

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 
NSDate *today = [NSDate date]; 
NSDateComponents *todayComps = [calendar components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:today]; 

NSDateComponents *comps = [calendar components:(NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:[timeOnlyFormatter dateFromString:string]]; 
comps.day = todayComps.day; 
comps.month = todayComps.month; 
comps.year = todayComps.year; 
NSDate *date = [calendar dateFromComponents:comps]; 
[calendar release]; 
[timeOnlyFormatter release]; 
[locale release]; 

有一点需要注意的是,当你判断时间是否准确时,你必须注意时区。例如,在我的应用程序中,当您停在断点处时,您将看到格林尼治标准时间(因此它看起来不同于输入时间,这是我的当地时间),但是当时间实际显示在屏幕上时应用程序,它被格式化显示在当地时区。您可能需要考虑这一点,以确定结果是实际上与您所期望的不同。

如果这没有帮助,你能否详细说明“没有给出想要的结果”?它给出的结果是什么,以及与预期的结果相比如何?

+0

我刚刚收到此错误:2015-01-16 12:14:05.864 TesInsta [26792:4444831] *** - [__ NSCFCalendar组件:fromDate:]:日期不能为零 未来异常。 这些错误中的一部分将与此投诉一起报告,那么进一步违规将被忽略。 下面是此次发生的回溯(由于编译器优化,可能会丢失一些帧): ( –

+0

)Downvote看起来有点苛刻,因为这个答案在三年半前发布时效果很好。这个例外从上面的答案或从您的代码?根据你报告的,看看这里:http://stackoverflow.com/questions/16094063/sending-nscfcalendar-nil-nsdate-sarcastic-error –

20

这很适合作为NSDate类别。

/** Returns a new NSDate object with the time set to the indicated hour, 
    * minute, and second. 
    * @param hour The hour to use in the new date. 
    * @param minute The number of minutes to use in the new date. 
    * @param second The number of seconds to use in the new date. 
    */ 
-(NSDate *) dateWithHour:(NSInteger)hour 
        minute:(NSInteger)minute 
        second:(NSInteger)second 
{ 
    NSCalendar *calendar = [NSCalendar currentCalendar]; 
    NSDateComponents *components = [calendar components: NSYearCalendarUnit| 
                 NSMonthCalendarUnit| 
                 NSDayCalendarUnit 
               fromDate:self]; 
    [components setHour:hour]; 
    [components setMinute:minute]; 
    [components setSecond:second]; 
    NSDate *newDate = [calendar dateFromComponents:components]; 
    return newDate; 
} 

通过上述类别,如果你有你想改变的时候现有的日期,你这样做是这样的:

NSDate *newDate = [someDate dateWithHour:10 minute:30 second:00];

但是,如果你尝试添加或从现有日期减去小时,一个类中的方法来做到这一点也很简单:

/** Returns a new date with the given number of hours added or subtracted. 
    * @param hours The number of hours to add or subtract from the date. 
    */ 
-(NSDate*)dateByAddingHours:(NSInteger)hours 
{ 
    NSDateComponents *components = [[NSDateComponents alloc] init]; 
    [components setHour:hours]; 

    return [[NSCalendar currentCalendar] 
       dateByAddingComponents:components toDate:self options:0]; 
} 
+1

在你的类别'dateWithHour:分钟:第二''日历'来自哪里? –

+0

@ Lukasz'Severiaan'Grela这是一个'[NSCalendar currentCalendar]'变量被排除在代码之外了 – memmons

+1

这是否适用于24h格式和AM/PM格式?例如,如果我这样调用函数:NSDate * newDate = [someDate dateWithHour:6 minute:30 second:00];那么“6”是6AM或6PM?显然,如果我在6点6点的24h格式。 – superpuccio

0
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; 
NSDateComponents *comps = [calendar components:(NSCalendarUnitHour | NSCalendarUnitMinute) fromDate:[NSDate date]]; 
comps.hour = 0; 
comps.minute = 15; 
NSDate *date = [calendar dateFromComponents:comps]; 

iOS 8

2

是Swift2

extension NSDate { 
    func dateWithHour (hour: Int, minute:Int, second:Int) ->NSDate?{ 

     let calendar = NSCalendar.currentCalendar(), 
      components = calendar.components([.Day,.Month,.Year], fromDate: self) 
     components.hour = hour; 
     components.minute = minute; 
     components.second = second; 

     return calendar.dateFromComponents(components) 
    } 
}