NSCalendar.components()。分钟返回不一致的值

在我的post,testing和代码在下面的链接遇到原始问题https://stackoverflow.com/questions/27339072/working-with-nsdate-components-in-swift/30822018#30822018

这是最小的testing案例

  1. 我创build一个date,从一个特定的date(自我在这种情况下,因为我在NSDate()扩展)使用NSCalendar.dateByAddingUnit(…,值:x,…)
  2. 然后,我使用NSCalendar.components(…,fromDate,toDate,…)得到“fromDate”(创builddate或自我)“toDate”(当前时间是NSDate())的差异。
  3. 如果x> 0,我在上面的步骤得到的答案是x-1。 如果x <0,我得到的答案是x。 x在上面的步骤1中定义。
  4. 这可能会导致使用人类可读属性(如过去3小时内的所有事件)过滤事件的错误,因为此行为导致180分钟不是三小时。
  5. 这不是步骤1中的错误,因为date打印正确,如在打印结束时看到的那样。

NSCalendar.components中有一个选项,我缺less或这是一个错误?

这是代码。

// // NSDateTest.swift // NSDateTestCase // // Created by Jitendra Kulkarni on 6/13/15. // import Foundation public extension NSDate { func xMins(x:Int) -> NSDate { return NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitMinute, value: x, toDate: self, options: nil)! } var hoursFromToday: Int{ var fromDate: NSDate = self var toDate: NSDate = NSDate() var sign: Int = -1 (fromDate,toDate, sign) = self.sanitizedDates() return (sign * NSCalendar.currentCalendar().components(.CalendarUnitHour, fromDate: fromDate, toDate: toDate, options: nil).hour) } var minsFromToday: Int{ var fromDate: NSDate = self var toDate: NSDate = NSDate() var sign: Int = 1 (fromDate,toDate) = self.sanitizedDates() return ( sign * NSCalendar.currentCalendar().components(.CalendarUnitMinute, fromDate: fromDate, toDate: toDate, options: nil).minute) } //Date Comparisons //https://stackoverflow.com/questions/26198526/nsdate-comparison-using-swift func isGreaterThanDate(dateToCompare : NSDate) -> Bool { //Declare Variables var isGreater = false //Compare Values if self.compare(dateToCompare) == NSComparisonResult.OrderedDescending { isGreater = true } //Return Result return isGreater } // Date printing conversions var timeDayMonthYear: String { let dateMonthYearFormatter: NSDateFormatter = NSDateFormatter() let currentLocale: NSLocale = NSLocale.currentLocale() let dateMonthYearFormatString: NSString! = NSDateFormatter.dateFormatFromTemplate("EdMMMyyyy' ' HH':'mm",options: 0, locale: currentLocale) dateMonthYearFormatter.dateFormat = dateMonthYearFormatString as! String return dateMonthYearFormatter.stringFromDate(self) } private func sanitizedDates() -> (fromDate: NSDate, toDate: NSDate) { var toDate: NSDate = self var fromDate: NSDate = NSDate() if(toDate.isGreaterThanDate(fromDate)) { // toDate = toDate.xMins(1) // Uncomment this to make the answer work } return (fromDate,toDate) } static func test (mins: Int = 0) { NSLog("****************** Start Testing of NSDate **************************") NSLog("Inputs: mins: \(mins)") var today = NSDate() NSLog("Today is: \(today.timeDayMonthYear)") var minsFromToday = today.xMins(mins) NSLog("** Date created \(mins) minutes from today is: \(minsFromToday.timeDayMonthYear)") NSLog("minsFromToday returns: \(minsFromToday.minsFromToday)"); NSLog("hoursFromToday returns: \(minsFromToday.hoursFromToday)"); NSLog("__________________ End Testing of NSDate _________________________") } } 

这里是NSDate(60)和NSDate(-60)的结果。 寻找*错误。 如果您从sanitizedDate()中的一条注释行中删除了注释,您将获得预期的结果。

 2015-06-13 14:56:44.877 NSDateTestCase[23136:1150501] ****************** Start Testing of NSDate ************************** 2015-06-13 14:56:44.878 NSDateTestCase[23136:1150501] Inputs: mins: 60 2015-06-13 14:56:44.882 NSDateTestCase[23136:1150501] Today is: Sat, Jun 13, 2015, 14:56 2015-06-13 14:56:44.883 NSDateTestCase[23136:1150501] ** Date created 60 minutes from today is: Sat, Jun 13, 2015, 15:56 2015-06-13 14:56:44.883 NSDateTestCase[23136:1150501] minsFromToday returns: 59 // *ERROR should be 60 2015-06-13 14:56:44.884 NSDateTestCase[23136:1150501] hoursFromToday returns: 0 // *ERROR should be 1 2015-06-13 14:56:44.884 NSDateTestCase[23136:1150501] __________________ End Testing of NSDate _________________________ 2015-06-13 14:56:44.884 NSDateTestCase[23136:1150501] ****************** Start Testing of NSDate ************************** 2015-06-13 14:56:44.884 NSDateTestCase[23136:1150501] Inputs: mins: -60 2015-06-13 14:56:44.885 NSDateTestCase[23136:1150501] Today is: Sat, Jun 13, 2015, 14:56 2015-06-13 14:56:44.885 NSDateTestCase[23136:1150501] ** Date created -60 minutes from today is: Sat, Jun 13, 2015, 13:56 2015-06-13 14:56:44.886 NSDateTestCase[23136:1150501] minsFromToday returns: -60 2015-06-13 14:56:44.886 NSDateTestCase[23136:1150501] hoursFromToday returns: -1 2015-06-13 14:56:44.893 NSDateTestCase[23136:1150501] __________________ End Testing of NSDate _________________________ 

下面是基于Kurt的答案下面的代码。 请注意,必须更改xFromToday API以获取关于“今天”的input:

 // // NSDateTest.swift // NSDateTestCase // // Created by Jitendra Kulkarni on 6/13/15. // import Foundation public extension NSDate { func xMins(x:Int) -> NSDate { return NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitMinute, value: x, toDate: self, options: nil)! } func hoursFromToday(today: NSDate) -> Int { var fromDate: NSDate = self var toDate: NSDate = today return (-NSCalendar.currentCalendar().components(.CalendarUnitHour, fromDate: fromDate, toDate: toDate, options: nil).hour) } func minsFromToday(today: NSDate) -> Int { var fromDate: NSDate = self var toDate: NSDate = today return (-NSCalendar.currentCalendar().components(.CalendarUnitMinute, fromDate: fromDate, toDate: toDate, options: nil).minute) } //Date Comparisions //https://stackoverflow.com/questions/26198526/nsdate-comparison-using-swift func isGreaterThanDate(dateToCompare : NSDate) -> Bool { //Declare Variables var isGreater = false //Compare Values if self.compare(dateToCompare) == NSComparisonResult.OrderedDescending { isGreater = true } //Return Result return isGreater } // Date printing converstions var timeDayMonthYear: String { let dateMonthYearFormatter: NSDateFormatter = NSDateFormatter() let currentLocale: NSLocale = NSLocale.currentLocale() let dateMonthYearFormatString: NSString! = NSDateFormatter.dateFormatFromTemplate("EdMMMyyyy' ' HH':'mm",options: 0, locale: currentLocale) dateMonthYearFormatter.dateFormat = dateMonthYearFormatString as! String return dateMonthYearFormatter.stringFromDate(self) } static func test (mins: Int = 0) { NSLog("****************** Start Testing of NSDate **************************") NSLog("Inputs: mins: \(mins)") var today = NSDate() NSLog("Today is: \(today.timeDayMonthYear)") var minsFromToday = today.xMins(mins) NSLog("** Date created \(mins) minutes from today is: \(minsFromToday.timeDayMonthYear)") //NSLog("minsFromToday returns: \(minsFromToday.minsFromToday)") NSLog("minsFromToday(today) returns: \(minsFromToday.minsFromToday(today))"); //NSLog("hoursFromToday returns: \(minsFromToday.hoursFromToday)") NSLog("hoursFromToday(today) returns: \(minsFromToday.hoursFromToday(today))"); NSLog("__________________ End Testing of NSDate _________________________") } 

这是产生的输出:

 2015-06-13 16:23:55.362 NSDateTestCase[23758:1196619] ****************** Start Testing of NSDate ************************** 2015-06-13 16:23:55.363 NSDateTestCase[23758:1196619] Inputs: mins: 60 2015-06-13 16:23:55.366 NSDateTestCase[23758:1196619] Today is: Sat, Jun 13, 2015, 16:23 2015-06-13 16:23:55.367 NSDateTestCase[23758:1196619] ** Date created 60 minutes from today is: Sat, Jun 13, 2015, 17:23 2015-06-13 16:23:55.367 NSDateTestCase[23758:1196619] minsFromToday(today) returns: 60 // All good now. 2015-06-13 16:23:55.367 NSDateTestCase[23758:1196619] hoursFromToday(today) returns: 1 // All good now. 2015-06-13 16:23:55.367 NSDateTestCase[23758:1196619] __________________ End Testing of NSDate _________________________ 2015-06-13 16:23:55.368 NSDateTestCase[23758:1196619] ****************** Start Testing of NSDate ************************** 2015-06-13 16:23:55.368 NSDateTestCase[23758:1196619] Inputs: mins: -60 2015-06-13 16:23:55.368 NSDateTestCase[23758:1196619] Today is: Sat, Jun 13, 2015, 16:23 2015-06-13 16:23:55.369 NSDateTestCase[23758:1196619] ** Date created -60 minutes from today is: Sat, Jun 13, 2015, 15:23 2015-06-13 16:23:55.370 NSDateTestCase[23758:1196619] minsFromToday(today) returns: -60 2015-06-13 16:23:55.380 NSDateTestCase[23758:1196619] hoursFromToday(today) returns: -1 2015-06-13 16:23:55.381 NSDateTestCase[23758:1196619] __________________ End Testing of NSDate _________________________ 

你在你的代码中的4个不同的地方调用NSDate()

每一个执行代码都会返回当前的date和时间所以它们会有一定的差别。

我怀疑你想在你的整个计算中使用“今天”的一个一致的值。 在代码的开始处调用一次NSDate() ,将其存储在一个variables中,并始终引用该variables。