Swift NSCalendar.currentCalendar().isDateInToday.() not working properly - ios

Because this post is related to comparing a given date to "today's date" keep in mind that I am posting this on a 2017-01-26
Basically, I am doing the following:
Getting an ISO DATE from the server
Transforming said date to an NSDate
using NSCalendar.currentCalendar().isDateInToday(myDate!) to actually check if that date is today.
However, it seems like I am doing something wrong, or missing something since the output seems abnormal.
I copied this output from my console:
String sent by the server --> 2017-1-27T0:00:00.000Z
Conversion I make with a dateFormatter --> (2017-01-27 00:00:00 +0000)
2017-01-27 00:00:00 +0000 is TODAY
The output above is obviously wrong. Because that is tomorrow, not today.
Now, in the following output, the date sent by the server is actually today but NSCalendar.currentCalendar().isDateInToday(myDate!) says otherwise
String sent by the server --> 2017-1-26T0:00:00.000Z
Conversion I make with a dateFormatter Optional(2017-01-26 00:00:00 +0000)
2017-01-26 00:00:00 +0000 is NOT TODAY
My question is, what could I be doing wrong?
I've double checked that my computer, the simulator and the dateFormatter.locale are properly set.
I've tried locales in string like "es_CL"
and also
dateFormatter.locale = NSLocale.currentLocale()

This is probably about the timezone. Your server returns dates is UTC, that is GMT-00:00.
If you are in Chile, your local timezone is -3 hours. Therefore today actually starts at 2017-01-26 03:00:00 +0000 and ends at 2017-01-27 03:00:00 +0000.
In that respect, the result you are seeing is completely correct. The returned daytime is not "today" in your local timezone.
To change this behavior, you can set the timezone on your calendar to UTC:
let calendar = NSCalendar.currentCalendar()
calendar.timeZone = TimeZone(secondsFromGMT: 0)

Related

Check if date has same day in swift

Hi there in my app I need to filter some documents through date. I need to see if the first date is the same day of the second date, so I searched on Apple Documentation to see if there are a solution to do this without create a method and I found this instruction isDate(_:inSameDayAs:), but if i try to compare the following date:
2020-07-29 16:15:50 +0000
2020-07-29 22:00:00 +0000
As you can see the day is the same, but I'm not able to understand why it return false, what's wrong?
CODE
Here's my code to check the difference between days:
myArray.filter({Calendar.current.isDate($0.log.createdDate, inSameDayAs:date)})
Date represents instants in time. Two instants of time could be in the same day in one timezone, but not in the same day in another timezone. These two instants in time:
2020-07-29 16:15:50 +0000
2020-07-29 22:00:00 +0000
are in the same day in the UTC timezone. However, in a timezone where the offset is 5 hours ahead of UTC (UTC+5) for example, the two times will not be in the same day, because they will become:
2020-07-29 21:15:50
2020-07-30 03:00:00
in that timezone
Now you should see that the timezone is crucial at determining whether two dates are in the same day.
Calendar.current uses the local timezone of the device for almost everything it does. isDate(_:inSameDayAs:) is no exception. In your device's timezone, the two dates are not in the same day. However, when you print them out without a formatter, they are always printed in the UTC timezone. In the UTC timezone, they are in the same day, making you think Calendar.current is wrong. Assuming you actually want to see if the two dates are in the same day in your device's timezone, then Calendar.current is right, and you don't need to fix anything.
To print the two dates in your timezone, use a formatter:
let formatter = DateFormatter()
formatter.dateStyle = .long
formatter.timeStyle = .long
print(formatter.string(from: yourDate))
If you actually want to see if the two dates are in the same UTC day, then you can set the timezone of the Calendar:
var calendar = Calendar.current
calendar.timeZone = TimeZone(identifier: "UTC")!
// call calendar.isDate(_:_sameDayAs:) rather than using Calendar.current

Wrong date on setting Calendar timeZone to UTC

Allover the app I use Date objects that when I NSLog the value it shows me:
2020-05-24 22:00:00 +0000
Which I think locally means the 25th (- 1 for summer, -1 for timezone). I want to do some Calendar date comparisons:
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = TimeZone(identifier: "UTC")!
// In order to have start on Monday
calendar.firstWeekday = 2
Using this calendar, lets say I want to get the starting date of current week:
extension Date
{
var startOfWeek: Date {
return Calendar.gregorian.date(from: Calendar.gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self))!
}
}
If I NSLog:
Date().startOfWeek
It will show me:
2020-05-25 00:00:00 +0000
If I disable the timeZone line on Calendar, it shows me:
2020-05-24 22:00:00 +0000
I always thought the second one is the correct UTC version. Am I wrong? Because I thought all core data dates, all dates are in the 2nd version. In short: If I set Calendar to UTC, my date comparissons are wrong. If I don't they are good. And all this time dates are in UTC.
You are wrong because CoreData dates are not affected by TimeZone. Dates are dates. Think of them as numeric values. When you translate that value to a date and hour then, and only then, the TimeZone is applied.
In your example everything is correct. For a calendar whose TimeZone is UTC, 2020-05-25 00:00:00 +0000 is the beginning of the week. If you use other TimeZone values (for example the default value from Locale) then the your week start at 2020-05-24 22:00:00 +0000. That means that in your TimeZone the hour is 2020-05-25 00:00:00.

Getting next date when trying to convert NSDate to String

I have this date in actuall
2016-09-03 19:00:00 +0000
Now I am trying to convert it to String using a specific format like below
But what I am getting in return is not as desired. the formatter is adding on day to the given date like below
Is this standard behaviour ?
This is not standard behaviour. This happen because of the time zone difference. Set time zone proper
Set the timezone.
formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation: #"GMT"];
When you hover over the date, you can see that it is showing UTC, whereas the formatter is automatically converting this to a local date. If your timezone is 5 hours ahead of UTC, then it will be the next day locally from that time.

Swift date formatting, getting the date back from server is not the same as sent to the server

I am trying to parse a date that is sent to the server.
Now the date that is recieved from the server is "2016-05-10T22:34:00.000Z"
And here is my code to get a formatted date out of the above date string :
let format="yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let dateFmt = NSDateFormatter()
dateFmt.dateFormat = format
let newreadableDate = dateFmt.dateFromString(dateString)
print(newreadableDate!)
dateFmt.dateFormat = "MMM dd hh:mm a"
print("Formatted date is : \(dateFmt.stringFromDate(newreadableDate!))")
The print statement prints the following result : May 11 04:04 AM
The above result is totally wrong. I should get back the same date that I recieved from server but with different format.
But the newReadableDate variable prints the correct date : 2016-05-10 22:34:00 +0000
But after I format it, it gives me wrong date.
What is wrong in the above code ?
Your code is fine. The output is correct. The date string you parse is in UTC time. But you log the final result in local time. You must live in a timezone that is 5.5 hours ahead of UTC.
The Z in the date string represents "Zulu" time which it UTC time. So the date formatter parses the string as a time in UTC time.
You then choose to print the resulting NSDate. By default, NSDateFormatter will generate a string from an NSDate in locale time.
May 10, 2016 at 22:34 UTC time is exactly the same time as May 11, 2016 at 04:04 am in your local (+0530) timezone.

convert NSDate to GMT timezone

I am working on NSDate and i am new for it.I have start date and end date,getting from user.And it is 2013-01-01 and 2013-02-19.When i try to display in console it is showing me 2012-12-31 18:30:00 +0000.So you can say 5:30 is gap.So i am adding time interval
startDate = [aStartdDate dateByAddingTimeInterval:19800];
endDate = [aEndDate dateByAddingTimeInterval:19800];
My question is when i am trying to get current week using 2012-12-31 18:30:00 +0000 date, it is showing me correctly.But when i use 2013-02-01 00:00:00 +0000 date,it is showing me total number of weeks in month.Please help me.Thanking you.
Timezones shouldn't be part of your model - They are a presentation problem.
Your model should always use a common default timezone. If you present the date to your users, apply a NSDateFormatter that uses a specific timezone.
In your case this means, that you shouldn't try to fix your dates by applying arbitrary intervals but use a date formatter in the final step (output) instead.

Resources