mike vorisis
mike vorisis

Reputation: 2832

Strange reaction when comparing dates with currentDate Swift

I have as the title says a very strange reaction when I compare dates with currentDate. Here is what happen: I do a query to my server to take some dates then I print them so I will be sure that it took them right (and everything is ok). Then I print currentDate which is appearing with 3 hours earlier. Ok I will fix it then I'm saying. BUT! when I'm trying to compare them I take only the dates that are 20:59 and earlier.

This is my code (//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)") 
                        }

                    }

This is my output

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

Upvotes: 4

Views: 1146

Answers (3)

mike vorisis
mike vorisis

Reputation: 2832

I finally found the answer of my question!

I found it here

What I did is this:

let utcCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)

Inside viewDidLoad I pu this:

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

and finnaly in my statement i put this:

if self.utcCalendar!.isDate and so on...

Thank you all for your answers!

EDIT!

If I want to print the date I have to change dateformatter too like this:

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

Upvotes: 0

fishinear
fishinear

Reputation: 6336

Greece summertime actually has a 3 hour difference with UTC. So the UTC 2016-07-28 21:00:00 +0000 time and later is actually in the next day in Greece. So if you compare that according to the local (Greece) calendar with:

NSCalendar.currentCalendar().isDate(dateevent, equalToDate: self.currentDate, toUnitGranularity: .Day)

then it will not compare equal.

If you want to compare according to UTC days instead, then set the timeZone of the calendar object to UTC:

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

If you want to compare according to some other timezone, then you obviously need to set the timeZone differently.


If you are OK with comparing the dates according to the local timezone, but are simply confused that the dates are printed in UTC, then use the following for converting to a string:

NSDateFormatter().stringFromDate(dateevent) 

Upvotes: 1

xoudini
xoudini

Reputation: 7031

I'm not going to discuss what time zones you should use on the server side, but the most convenient and consistent way is UTC. As you're already using UTC time zones on your server, you need to take this into account when storing dates and times on your server. What I mean with this, is that if you're storing e.g. 2016-07-28 21:00:00 +0000, it doesn't necessarily translate to 2016-07-28 21:00:00 at your location.

See the following:

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

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

The time object printed out as it is outputs the current time in UTC. As a reference, the local time zone for me also happens to be UTC+3, so the local time is 2016-07-28 18:23:02 +0300.

Let's look at a few dates in string format next:

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.
]

And now, let's convert those strings into NSDate objects, which again, will remain in the UTC time zone:

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)
}

Next, we'll convert the NSDate objects to strings with the local format, which is probably where your confusion stems from:

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

Upvotes: 3

Related Questions