【问题标题】:How to set time on NSDate?如何在 NSDate 上设置时间?
【发布时间】:2011-11-09 11:03:50
【问题描述】:

我想用我想要的小时:分钟:秒来设置 NSDate 时间 目前我正在使用 NSDate 组件,但它没有给出预期的结果

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

【问题讨论】:

  • NSDate 旨在表示一个真实的时间日期。您是否尝试为实际日期设置时间组件?

标签: objective-c nsdate nsdatecomponent


【解决方案1】:

您的方法应该可以正常工作。我需要一个解决这种类型问题的方法(设置单独的日期组件),下面的代码按我的预期工作。我的情况:我想创建一个使用当前日期但将时间设置为作为字符串传入的值的日期对象。

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];

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

如果这没有帮助,您能否详细说明“没有给出预期的结果”?它给出了什么结果,与您的预期相比如何?

【讨论】:

  • 我刚刚收到此错误:2015-01-16 12:14:05.864 TesInsta[26792:4444831] *** -[__NSCFCalendar components:fromDate:]: date cannot be nil Future exception .此投诉将报告其中一些错误,然后将忽略进一步的违规行为。这是这次发生的回溯(由于编译器优化,某些帧可能会丢失):(
  • Downvote 似乎有点苛刻,因为这个答案在三年半前发布时效果很好。您是从上面的答案还是从您的代码中得到这个异常的?根据您报告的内容,请看这里:stackoverflow.com/questions/16094063/…
【解决方案2】:

这很适合作为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];
}

【讨论】:

  • 在您的类别dateWithHour:minute:secondcalendar 来自哪里?
  • @Lukasz'Severiaan'Grela 这是代码中忽略的[NSCalendar currentCalendar] 变量。已添加。
  • 这对 24 小时制和 AM/PM 格式都适用吗?例如,如果我这样调用函数: NSDate *newDate = [someDate dateWithHour:6 minute:30 second:00]; “6”是早上 6 点还是下午 6 点?显然,如果我采用 24 小时制,那么 6 点就是早上 6 点。
【解决方案3】:
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

【讨论】:

    【解决方案4】:

    是 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)
        }
    }
    

    【讨论】:

      【解决方案5】:

      您可以将 0 设置为小时、分钟和秒。

      NSDateFormatter *tFmt = [[NSDateFormatter alloc] init];
      
      tFmt.dateFormat = @"yyyy-MM-dd";
      
      NSString *strNowDate = [NSString stringWithFormat:@"%@ 00:00:00",[tFmt stringFromDate:[NSDate date]]];
      
      NSDate *nowDate = [NSDate dateWithString:strNowDate formatString:@"yyyy-MM-dd HH:mm:ss"];
      

      【讨论】:

        【解决方案6】:

        Swift 5 解决方案(基于@dattk 答案),适用于那些担心弃用警告的人 :)

        func date(withHour hour: Int, withMinute minute: Int, withSeconds second: Int) -> Date? { 
           let now = Date() 
           let calendar = NSCalendar.current 
           var components = calendar.dateComponents([.day,.month,.year], from: now)   
           components.hour = hour 
           components.minute = minute 
           components.second = second 
           return calendar.date(from: components) 
        }
        

        【讨论】:

          猜你喜欢
          • 2011-07-18
          • 2013-07-25
          • 1970-01-01
          • 1970-01-01
          • 2012-02-09
          • 1970-01-01
          • 1970-01-01
          • 2011-04-09
          • 1970-01-01
          相关资源
          最近更新 更多