【问题标题】:How can I get an NSDate object for today at midnight?如何在午夜获得今天的 NSDate 对象?
【发布时间】:2012-02-20 20:33:55
【问题描述】:

获取表示当天午夜的 NSDate 对象的最有效方法是什么?

【问题讨论】:

    标签: objective-c cocoa-touch nsdate


    【解决方案1】:

    从 iOS8 开始,您可以使用 startDayForDate。

    所以,为了得到今天的开始(目标-C):

    NSDate * midnight;
     midnight = [[NSCalendar currentCalendar] startOfDayForDate: [NSDate date]];
    

    【讨论】:

      【解决方案2】:

      斯威夫特:

      let cal = NSCalendar.currentCalendar()
      
      //tip:NSCalendarUnit can be omitted, but with the presence of it, you can take advantage of Xcode's auto-completion
      var comps = cal.components(NSCalendarUnit.YearCalendarUnit | .MonthCalendarUnit | .DayCalendarUnit | .HourCalendarUnit | .MinuteCalendarUnit | .SecondCalendarUnit, fromDate: NSDate()) 
      comps.hour = 0
      comps.minute = 0
      comps.second = 0
      
      let midnightOfToday = cal.dateFromComponents(comps)!
      

      斯威夫特 2.2:

      let cal = NSCalendar.currentCalendar()
      
      let comps = cal.components([.Year, .Month, .Day, .Hour, .Minute, .Second], fromDate: NSDate())
      comps.hour = 0
      comps.minute = 0
      comps.second = 0
      
      let midnightOfToday = cal.dateFromComponents(comps)!
      

      目标-C:

      NSCalendar *cal = [NSCalendar currentCalendar]; 
      
      NSDateComponents *comps = [cal components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute) fromDate:[NSDate date]];    
      [comps setHour:0]; 
      [comps setMinute:0]; 
      [comps setSecond:0];
      
      NSDate *midnightOfToday = [cal dateFromComponents:comps];
      

      【讨论】:

        【解决方案3】:
        NSCalendar *cal = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease]; 
        [cal setTimeZone:[NSTimeZone systemTimeZone]];  
        
         NSDateComponents * comp = [cal components:( NSYearCalendarUnit| NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:[NSDate date]]; 
        
         [comp setMinute:0]; 
         [comp setHour:0];
         [comp setSecond:0]; 
        
         NSDate *startOfToday = [cal dateFromComponents:comp]; 
        

        如果您的意思是午夜 23:59,则将组件的小时设置为 23,分钟设置为 59。

        【讨论】:

          【解决方案4】:
              let calendar = NSCalendar.currentCalendar()
              let unitFlags: NSCalendarUnit = [.Year, .Month, .Day, .Minute, .Second]
              let components = calendar.components(unitFlags , fromDate: NSDate())
          
              components.hour = 0
              components.minute = 0
              components.second = 0
          
              //Gives Midnight time of today
              let midnightOfToday = calendar.dateFromComponents(components)!
          

          【讨论】:

          • 对你的答案做一些解释,为什么 OP 使用这个
          【解决方案5】:

          你可以使用NSCalendardateBySettingHour:minute:second:ofDate:options:

          所以就这么简单:

          NSCalendar *calendar = [NSCalendar currentCalendar];
          calendar.timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
          
          NSDate *midnight = [calendar dateBySettingHour:0 minute:0 second:0 ofDate:[NSDate date] options:0];
          

          【讨论】:

            【解决方案6】:

            iOS 8 中的新 API

            iOS 8 在 NSCalendar 上包含一个名为 startOfDayForDate 的新方法,它非常易于使用:

            let startOfToday = NSCalendar.currentCalendar().startOfDayForDate(NSDate())
            

            苹果的描述:

            此 API 返回给定日期的第一个时刻日期。 传入 [NSDate date],例如,如果您想要“今天”的开始。 如果有两个午夜,则返回第一个。如果不存在,则返回确实存在的第一个时刻。

            关于时区的更新:

            由于 startOfDayForDate 是 NSCalendar 上的一个方法,它使用 NSCalendar 的时区。因此,如果我想知道现在是在纽约几点钟,今天从洛杉矶开始,我可以这样做:

            let losAngelesCalendar = NSCalendar.currentCalendar().copy() as! NSCalendar
            losAngelesCalendar.timeZone = NSTimeZone(name: "America/Los_Angeles")!
            
            let dateTodayBeganInLosAngeles = losAngelesCalendar.startOfDayForDate(NSDate())
            dateTodayBeganInLosAngeles.timeIntervalSince1970
            
            let dateFormatter = NSDateFormatter()
            dateFormatter.dateStyle = .MediumStyle
            dateFormatter.timeStyle = .ShortStyle
            dateFormatter.timeZone = NSTimeZone(name: "America/New_York")!
            let timeInNewYorkWhenTodayBeganInLosAngeles = dateFormatter.stringFromDate(dateTodayBeganInLosAngeles)
            print(timeInNewYorkWhenTodayBeganInLosAngeles) // prints "Jul 29, 2015, 3:00 AM"
            

            【讨论】:

            • 这是否处理时区?
            • @ftvs,是的,因为 startOfDayForDate() 是 NSCalendar 上的一个方法,您可以在 NSCalendar 实例上设置 timeZone。我上面包含的示例代码使用 NSCalender.currentCalendar() ,它使用用户的当前时区。您可以创建自己的 NSCalendar 并将时区设置为不同的值。
            • @ftvs,我更新了我的答案,提供了有关时区的更多信息。
            • 这应该是公认的答案,尤其是对于 iOS 8 及更高版本。
            • @ndmeri 为什么这应该是公认的答案?这是使用 Swift 的答案,是的,但没有为 Objective C 提供答案。
            【解决方案7】:

            试试这个:

            NSDate *const date = NSDate.date;
            NSCalendar *const calendar = NSCalendar.currentCalendar;
            NSCalendarUnit const preservedComponents = (NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay);
            NSDateComponents *const components = [calendar components:preservedComponents fromDate:date];
            NSDate *const normalizedDate = [calendar dateFromComponents:components];
            

            【讨论】:

            • 您在此处发布的日期字符串显然已记录在模拟器中。这会自动适应您的时区,但实际存储的日期是午夜。
            • 你是如何得到你的字符串的?
            • 那是我的观点。 NSLog(@"%@", date); 正在向它发送 -description 消息,这与 NSLog 将其发送到控制台基本相同。如果您实际询问其NSHourCalendarUnit 的日期,您会发现它是午夜日期。
            • 这不正是我告诉你的吗?
            • 看起来从 iOS 8 开始,组件现在是 NSCalendarUnitYear、NSCalendarUnitMonth 和 NSCalendarUnitDay,以防有人收到弃用警告。
            【解决方案8】:
            NSDate *now = [NSDate date];
            NSDate *beginningOfToday = nil;
            [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&beginningOfToday interval:NULL forDate:now];
            

            【讨论】:

              【解决方案9】:

              您可以使用以下方法获取 NSDate 的午夜值。

              - (NSDate *)dateAtBeginningOfDayForDate:(NSDate *)inputDate
              {
                  // Use the user's current calendar and time zone
                  NSCalendar *calendar = [NSCalendar currentCalendar];
                  NSTimeZone *timeZone = [NSTimeZone systemTimeZone];
                  [calendar setTimeZone:timeZone];
              
                  // Selectively convert the date components (year, month, day) of the input date
                  NSDateComponents *dateComps = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:inputDate];
              
                  // Set the time components manually
                  [dateComps setHour:0];
                  [dateComps setMinute:0];
                  [dateComps setSecond:0];
              
                  // Convert back       
                  NSDate *beginningOfDay = [calendar dateFromComponents:dateComps];
                  return beginningOfDay;
              }
              

              Thkis 取自这里website

              【讨论】:

                【解决方案10】:

                试试这个:

                NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
                NSDate *now = [NSDate date];
                NSDateComponents *components = [gregorian components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:now];
                NSDateFormatter* df = [[NSDateFormatter alloc]init];
                [df setDateFormat:@"MM/dd/yyyy HH:mm:ss.SSS"];
                NSLog(@"%@",[df stringFromDate:[gregorian dateFromComponents:components]]);
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2011-10-14
                  • 2020-09-30
                  • 2021-09-23
                  • 2012-10-19
                  • 1970-01-01
                  • 2014-11-29
                  • 2013-08-25
                  相关资源
                  最近更新 更多