将日期与currentDate Swift比较时的奇怪反应

时间:2016-07-28 13:48:52

标签: ios swift date

当我将日期与currentDate进行比较时,我有一个非常奇怪的反应。 这是发生的事情: 我对我的服务器进行查询以获取一些日期然后我打印它们以便我确定它正确(并且一切正常)。 然后我打印出3小时前出现的currentDate。 好的,我会解决它,然后我说。 但!当我试图比较它们时,我只采用20:59及更早的日期。

这是我的代码(//dateevent are the dates that I recover from server

if dateevent.earlierDate(self.currentDate).isEqualToDate(self.currentDate){
   print("All dates \(dateevent)")
   if NSCalendar.currentCalendar().isDate(dateevent, equalToDate: self.currentDate, toUnitGranularity: .Day){
     print("here is what it passed from server \(dateevent)")
     print("here is the current date \(self.currentDate)") 
                        }

                    }

这是我的输出

All dates 2016-07-28 19:00:00 +0000
here is what it passed from server 2016-07-28 19:00:00 +0000
here is the current date 2016-07-28 13:43:51 +0000

All dates 2016-07-28 19:00:00 +0000
here is what it passed from server 2016-07-28 19:00:00 +0000
here is the current date 2016-07-28 13:43:51 +0000

All dates 2016-07-28 21:00:00 +0000
All dates 2016-07-28 21:00:00 +0000
All dates 2016-07-28 23:30:00 +0000
All dates 2016-07-29 21:00:00 +0000
All dates 2016-07-29 22:30:00 +0000
All dates 2016-07-29 23:00:00 +0000
All dates 2016-07-29 23:00:00 +0000
All dates 2016-07-29 23:30:00 +0000
All dates 2016-07-30 21:00:00 +0000

3 个答案:

答案 0 :(得分:3)

我不打算讨论您应该在服务器端使用哪些时区,但最方便和一致的方式是UTC。由于您已经在服务器上使用UTC时区,因此在服务器上存储日期和时间时需要考虑到这一点。我的意思是,如果你要存储,例如2016-07-28 21:00:00 +0000,它不一定会转移到您所在位置的2016-07-28 21:00:00

请参阅以下内容:

let time = NSDate()        // Create an object for the current time.

print(time, "\n")          // Sample output: 
                              2016-07-28 15:23:02 +0000

打印出time对象,因为它以UTC格式输出当前时间。作为参考,我的本地时区也恰好是UTC + 3,因此本地时间为2016-07-28 18:23:02 +0300

让我们看一下下面的字符串格式的几个日期:

let strings = [
    "2016-07-28 19:00:00 +0000",
    "2016-07-28 20:00:00 +0000",
    "2016-07-28 20:59:59 +0000", // Second before midnight, UTC+3.
    "2016-07-28 21:00:00 +0000", // Midnight in UTC+3.
    "2016-07-28 22:00:00 +0000",
    "2016-07-28 23:30:00 +0000",
    "2016-07-28 23:59:59 +0000", // Second before midnight, UTC.
    "2016-07-29 00:00:00 +0000"  // Midnight in UTC.
]

现在,让我们将这些字符串转换为NSDate个对象,这些对象将再次保留在UTC时区:

var dates: [NSDate] = []

for string in strings {
    let formatter = NSDateFormatter()
    formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
    guard let date = formatter.dateFromString(string) else { continue }
    dates.append(date)
}

接下来,我们将NSDate对象转换为具有本地格式的字符串,这可能是您的困惑源于:

for date in dates {
    print("Current time in UTC: ", time)
    print("Date in UTC:         ", date)

    let formatter = NSDateFormatter()
    formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
    formatter.timeZone = NSTimeZone.localTimeZone()
    print("Current local time:  ", formatter.stringFromDate(time))
    print("Date in local time:  ", formatter.stringFromDate(date))
}

// Sample output for the date 2016-07-28 19:00:00 +0000:
// Current time in UTC:  2016-07-28 15:23:02 +0000
// Date in UTC:          2016-07-28 19:00:00 +0000
// Current local time:   2016-07-28 18:23:02
// Date in local time:   2016-07-28 22:00:00

答案 1 :(得分:1)

希腊夏令时实际上与UTC有3小时的差异。所以UTC 2016-07-28 21:00:00 +0000时间及以后实际上是在希腊的第二天。因此,如果您根据当地(希腊)日历将其与:

进行比较
NSCalendar.currentCalendar().isDate(dateevent, equalToDate: self.currentDate, toUnitGranularity: .Day)

然后它不会比较平等。

如果您想根据UTC天数进行比较,请将日历对象的timeZone设置为UTC:

NSCalendar *calendar = NSCalender.currentCalendar();
calendar.timeZone = NSTimeZone.timeZoneForSecondsFromGMT(0);
if (calendar.isDate(dateevent, equalToDate: self.currentDate, toUnitGranularity: .Day)) ...

如果您想根据其他时区进行比较,那么您显然需要以不同的方式设置timeZone

如果您可以根据当地时区比较日期,但只是混淆日期以UTC格式打印,请使用以下内容转换为字符串:

NSDateFormatter().stringFromDate(dateevent) 

答案 2 :(得分:0)

我终于找到了我的问题的答案!

我发现它here

我做的是:

let utcCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)

在viewDidLoad里面我这样说:

utcCalendar!.timeZone = NSTimeZone(abbreviation: "UTC")!

并且在我的陈述中我把它放在了:

if self.utcCalendar!.isDate等等......

谢谢大家的答案!

EDIT!

如果我想打印日期,我必须更改dateformatter:

dateFormatter.timeZone = NSTimeZone(abbreviation: "UTC")!