【问题标题】:NSCalendar components returning different valuesNSCalendar 组件返回不同的值
【发布时间】:2015-11-28 07:40:55
【问题描述】:

我有 2 个日期要比较。未来的日期和当前日期。当我比较它们时,我想检索它们在小时、分钟和秒方面的差异。我相信我必须这样做的代码是正确的,但是,我会根据我请求的组件返回不同的值。

我对所有示例都使用以下日历:

let calendar = NSCalendar.currentCalendar()

答:

let dateComponents = calendar.components([NSCalendarUnit.Year, NSCalendarUnit.Month, NSCalendarUnit.Day, NSCalendarUnit.Hour, NSCalendarUnit.Second, NSCalendarUnit.Minute], fromDate: NSDate(), toDate: date, options: [])

乙:

let dateComponents2 = calendar.components(.Hour, fromDate: NSDate(), toDate: date, options: [])

因此,对于上面的示例,dateComponents.hour 等于 dateComponents2.hourdateComponents2.hour 返回正确的值。

更有趣的是下面的案例:

答:

let dateComponents = calendar.components([NSCalendarUnit.Year, NSCalendarUnit.Month, NSCalendarUnit.Day, NSCalendarUnit.Hour, NSCalendarUnit.Second, NSCalendarUnit.Minute], fromDate: NSDate(), toDate: date, options: [])

乙:

let dateComponents2 = calendar.components(.Minute, fromDate: NSDate(), toDate: date, options: [])

现在,dateComponents.minute 等于 dateComponents2.minute,但现在 dateComponents.minute 返回正确的值。

为什么会发生这种情况?我同时请求多个组件这一事实是否会影响返回值?

编辑 以下是使用以下日期的一些示例。返回值显示为小时、分钟、秒:

2015-11-29 10:59:00 +0000

2015-11-28 07:57:20 +0000

使用日期组件:

3、1、39

使用 dateComponents2(每个组件一个):

27、1621、97299

dateComponents2 中的小时值是正确的,而 dateComponents 中的分钟和秒值是正确的。

【问题讨论】:

  • @Rob 抱歉,我现在将发布示例日期和返回值!这些值与您的示例中的值不同......
  • @Rob 我已经用实际日期编辑了这个问题。有什么想法吗?

标签: ios cocoa-touch nsdate nscalendar


【解决方案1】:

假设两个 NSDate 对象相隔 61 秒,如果同时得到分和秒,则得到 1 分 1 秒,但如果只要求秒,则得到 61 秒:

let date1 = NSDate()
let date2 = date1.dateByAddingTimeInterval(61)

let calendar = NSCalendar.currentCalendar()
let components1 = calendar.components([.Minute, .Second], fromDate: date1, toDate: date2, options: [])
let components2 = calendar.components([.Second], fromDate: date1, toDate: date2, options: [])

print("\(components1.minute) minute and \(components1.second) second")
print("\(components2.second) seconds")

产生:

1 分 1 秒
61 秒


使用您的日期(并在计算中添加天数和小时数):

let dateString1 = "2015-11-28 07:57:20 +0000"
let dateString2 = "2015-11-29 10:59:00 +0000"

let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"

let date1 = formatter.dateFromString(dateString1)!
let date2 = formatter.dateFromString(dateString2)!

let calendar = NSCalendar.currentCalendar()
let components1 = calendar.components([.Day, .Hour, .Minute, .Second], fromDate: date1, toDate: date2, options: [])
let components2 = calendar.components([.Second], fromDate: date1, toDate: date2, options: [])

print("\(components1.day) day, \(components1.hour) hours, \(components1.minute) minute, and \(components1.second) seconds")
print("\(components2.second) seconds")

产生:

1 天 3 小时 1 分 40 秒
97300秒

如果你把它相乘,你会发现 1 天 3 小时 1 分 40 秒等于 97300 秒。


您还可以考虑使用NSDateComponentsFormatter 创建格式良好(且本地化)的已用时间字符串表示形式:

let componentsFormatter = NSDateComponentsFormatter()
componentsFormatter.allowedUnits = [.Day, .Hour, .Minute, .Second]
componentsFormatter.unitsStyle = .Full
print(componentsFormatter.stringFromDate(date1, toDate: date2))

// or just show the top two units (because if you're showing days/hours, you probably no longer care about minutes/seconds

componentsFormatter.maximumUnitCount = 2
print(componentsFormatter.stringFromDate(date1, toDate: date2))

// but if you want actual total number of seconds, then change `allowedUnits` to use only that

componentsFormatter.allowedUnits = [.Second]
print(componentsFormatter.stringFromDate(date1, toDate: date2))

这将显示三个可选字符串:

1 天 3 小时 1 分钟 40 秒
1 天 3 小时
97,300 秒

【讨论】:

  • 这如何解释我上面的示例中的小时值不正确?不过,我开始明白你的意思了。但我仍然不明白为什么我会得到完全不同的价值观......
  • 啊,我想我现在明白了。所以问题是我在请求中包含了年、月和日组件,因此为了增加 1 天,时间被减少了。谢谢!
  • 没错!顺便说一句,如果您的意图是向用户显示此内容,我通常会绕过NSDateComponents 并使用NSDateComponentsFormatter,它自己进行组件计算并输出一个漂亮的(本地化)字符串。
猜你喜欢
  • 2019-03-20
  • 2017-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多