我创建了两个日期,如下所示:
let date1 = stringToDate("2015-02-12 12:29:29")!
let date2 = stringToDate("2015-02-11 19:18:49")!
func stringToDate(var dateString: String) -> NSDate? {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = NSTimeZone(name: "UTC")
return dateFormatter.dateFromString(dateString)
}
如您所见,这两个日期不同,并且不在同一天。
为了测试两个日期是否在同一天,我使用以下方法:
func isSameDayThan(date1: NSDate, date2: NSDate) -> Bool {
let calendar = NSCalendar.currentCalendar()
calendar.timeZone = NSTimeZone(abbreviation: "GMT+10")!
return calendar.compareDate(date1, toDate: date2, toUnitGranularity: .DayCalendarUnit) == .OrderedSame
}
我在日历中没有精确的任何时间区域。我的设备的本地TimeZone设置为GMT + 10.
在这种情况下,isSameDayThan(date1, date2)
- >真
如果我将timeZone更改为低于或等于GMT + 04的值,那么我得到isSameDayThan(date1, date2)
- >假的。
我不明白的是,结果因timeZone而异,但我比较两个NSDate()和NSDate()与时区无关,如果我没错。
答案 0 :(得分:1)
两个日期是UTC时区的不同日期。但在GMT + 10时区,他们都是同一天 - 2月12日。
2015-02-12 12:29:29 UTC = 2015-02-12 22:29:29 UTC + 10
2015-02-11 19:18:49 UTC = 2015-02-12 05:18:49 UTC + 10
默认情况下,比较在本地时区完成,但日期对象是在UTC时区专门创建的。
如果使用默认时区从字符串创建NSDate对象并使用默认时区进行比较,则日期将有两个不同的日期。
答案 1 :(得分:1)
时区发挥作用是因为您将日期与时区相关的粒度进行比较。所以你实际上是在与日期的本地表示进行比较。通常用于描述NSDate的时间点模型不知道几天和几周。从抽象的角度来看(即宇宙中无处不在的时间点)它实际上甚至不知道秒数。
无论如何,如果你要与==
进行比较,你显然不需要时区。这是唯一真正独立于当地代表性的比较。如果两个时间点完全相同,则它们是相等的。简单。
直接==
比较之外的所有内容都必须转换为本地单位。您不仅必须使用正确的日历,还必须使用正确的时区。
幸运的是,没有日历的日期短于或长于24小时。并且没有时区在几秒钟内也有所不同。因为我们知道,您可以通过简单的计算实际查看日期是否在同一分钟内。 e.g:
Int(date1.timeIntervalSince1970 / 60) == Int(date2.timeIntervalSince1970 / 60)
不需要日历,因为我们(目前)没有日期不是60秒的日历。不需要时区,因为我们没有时区,其偏移量的秒数不同。
但是我们有几个时区的偏移量只有一小时。例如印度时区的偏移量为+05:30。因此,从小时开始,粒度单位的边界取决于时区。
如果您有两个NSDate设置为9:25和9:35 UTC,如果您在任何时区中进行比较时,它们处于相同的小时,其偏移量的分钟数没有差异(例如{{ 1 +} in + x:00)。它们在UTC的同一小时内,它们在UTC + 5:00和UTC-5:00的同一小时内。
但如果你在印度时区进行比较,这两个日期实际上是在不同时间。因为IST的9:25 UTC是2:55,而IST的9:35 UTC是3:05。
在您的示例中,您将与当天的粒度进行比较。哪个需要考虑所有时区。但我们仍然可以忽略日历,因为所有日历都使用24小时的日期。
但是如果你要比较一周,一个月或一年的粒度,你也必须考虑日历。有些日历完全不同。仅仅因为两个日期在同一个月的格里高利日历中并不意味着他们在希伯来日历中的同一个月。
是的,这很复杂。这就是所有日期计算看起来如此冗长的原因。人们经常试图隐藏花哨辅助函数背后的复杂性。这通常会导致问题。因此,请注意00
等创建函数
每次比较日期时,您必须决定使用哪个时区和日历。如果您依赖辅助函数,您将错过一个实际应与UTC而不是本地时区进行比较的实例。
TL; DR:如果您与粒度进行比较,则应始终设置正确的日历和正确的时区。