SWIFT: Timezone issue when converting string to NSDate object [duplicate] - ios

I have a NSString (ex. "2011-04-12 19:23:39"), and what I did to format it to a NSDate was the following:
[inputFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *date = [inputFormatter dateFromString:newDateString];
but what it outputs when I nslog the date is this:
2011-04-12 23:23:39 +0000
which is about 4 hours off. Is there something I missed? Possibly a time zone problem?

The answer in short, is the Date is being returned GMT unless specified otherwise. You can set your timezone to get the correct date. If you plan on using the date in the app to set anything ( like localNotification time or Event ) you will need to do something special with the date because if you set the date in the iPhone it will be set as GMT time and will be off by a few hours. ( in your case 4 hours ). I do this exact thing I just described in one of my apps.
I made a mess of trying to get this to work correctly without having the hours be off. It was a huge PITA to figure out but its working now. I have copied, pasted, and edited my code to share. Again, its messy but it works! The pickerChanged is getting its info from a UIDatePicker
Using the code below. To answer your question, you can stop at "destinationDate". That will return to you the corrected time for your current time zone. I just provided the extra incase you were trying to use the date in the Phone somewhere.
NOTE: for a quick example i put the Event reminder in the same function as the datepicker, you will NOT want to do that otherwise you will have alot of reminders set everytime the wheel scrolls in the datepicker.
The code is below.
- (void)pickerChanged:(id)sender
{
NSLog(#"value: %#",[sender date]);
NSDate* date= [sender date];
NSDateFormatter *formatter=[[[NSDateFormatter alloc]init]autorelease];
[formatter setDateFormat:#"MM/dd/yyyy hh:mm:ss a"];
[formatter setTimeZone:[NSTimeZone systemTimeZone]];
[formatter setTimeStyle:NSDateFormatterLongStyle];
NSString *dateSelected =[formatter stringFromDate:date];
NSString *timeZone = [dateSelected substringFromIndex:12];
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];
//here we have to get the time difference between GMT and the current users Date (its in seconds)
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:date];
//need to reverse offset so its correct when we put it in the calendar
correctedTimeForCalendarEvent = destinationGMTOffset + (2*(-1*destinationGMTOffset));
//date to enter into calendar (we will use the correctedTimeForCalendarEvent to correct the time otherwise it will be off by a few hours )
NSDate * destinationDate = [[[NSDate alloc] initWithTimeInterval:destinationGMTOffset sinceDate:date] autorelease];
NSDate * dateForReminder = destinationDate;
// return destinationDate;
NSLog(#"value: %# - %#",destinationDate,dateForReminder);
//DO NOT put this code in this same function this is for a quick example only on StackOverflow
//otherwise you will have reminders set everytime the users scrolled to a different time
//set event reminder
//make sure to import EventKit framework
EKEventStore *eventDB = [[[EKEventStore alloc] init]autorelease];
EKEvent *myEvent = [EKEvent eventWithEventStore:eventDB];
NSString * eventTitle = [NSString stringWithFormat:#"%# - %#",app.dealerBusinessName,serviceOrComments.text];
myEvent.title = eventTitle;
//double check date one more time
NSLog(#"value: %#",destinationDate);
//set event time frame (1 hour) the "initWithTimeInterval" is where we account for the users timezone by adding the correctedTime from GMT to the calendar time ( so its not off by hours when entering into calendar)
myEvent.startDate = [[[NSDate alloc] initWithTimeInterval:correctedTimeForCalendarEvent sinceDate:destinationDate ]autorelease];
myEvent.endDate = [[[NSDate alloc] initWithTimeInterval:3600 sinceDate:myEvent.startDate]autorelease];
myEvent.allDay = NO;
//set event reminders 1 day and 1 hour before
myAlarmsArray = [[[NSMutableArray alloc] init] autorelease];
EKAlarm *alarm1 = [EKAlarm alarmWithRelativeOffset:-3600]; // 1 Hour
EKAlarm *alarm2 = [EKAlarm alarmWithRelativeOffset:-86400]; // 1 Day
[myAlarmsArray addObject:alarm1];
[myAlarmsArray addObject:alarm2];
myEvent.alarms = myAlarmsArray;
[myEvent setCalendar:[eventDB defaultCalendarForNewEvents]];
NSError *err;
[eventDB saveEvent:myEvent span:EKSpanThisEvent error:&err];
if (err == noErr) {
//no error, but do not show alert because we do that below.
}
}

NSDateFormatter use the current device timezone when it created the NSDate object. NSDate stores the date/time in GMT. Therefore by default NSLog will output the date/time in GMT+0. So, there's nothing wrong with your code. Now if you want to output the NSDate to your current timezone, your will have to use a NSDateFormatter object.

Your data and date formatter omit the TimeZone specifier. So something like this:
[inputFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ssZ"];
Would work - the Z is the timezone specifier and will parse both numeric offsets and timezone codes. Although in your case as your input date has no TimeZone information it won't work.
Your correct Time string should be like "2011-04-12 19:23:39 -0400" or "2011-04-12 19:23:39 EST "
Depending on where you get your date from, you should fix that to produce a fully qualified date if you can't do that, you will have to agree timezone offsets with the server or simply 'hard code' a timezone offset and add that number of seconds to your NSDate.

The date is being logged as a UTC date can be seen by the +0000 at the end. The date format you are using to parse the string assumes your local time zone which is presumably 4 hours behind UTC with daylight savings and the standard -5 hours.

Use -[NSDateFormatter setTimeZone:] to provide the date formatter with timezone information. You can use the local time zone, or if you have a fixed time zone associated with the date information, I recommend creating the timezone with the name (such as "America/East") rather than the abbreviation (such as "EST" or "EDT"), since the name does not force daylight savings into effect, but uses the correct daylight savings offset for that date in that timezone.

Related

Swift NSDateFormatter timezone not working [duplicate]

I have a NSString (ex. "2011-04-12 19:23:39"), and what I did to format it to a NSDate was the following:
[inputFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *date = [inputFormatter dateFromString:newDateString];
but what it outputs when I nslog the date is this:
2011-04-12 23:23:39 +0000
which is about 4 hours off. Is there something I missed? Possibly a time zone problem?
The answer in short, is the Date is being returned GMT unless specified otherwise. You can set your timezone to get the correct date. If you plan on using the date in the app to set anything ( like localNotification time or Event ) you will need to do something special with the date because if you set the date in the iPhone it will be set as GMT time and will be off by a few hours. ( in your case 4 hours ). I do this exact thing I just described in one of my apps.
I made a mess of trying to get this to work correctly without having the hours be off. It was a huge PITA to figure out but its working now. I have copied, pasted, and edited my code to share. Again, its messy but it works! The pickerChanged is getting its info from a UIDatePicker
Using the code below. To answer your question, you can stop at "destinationDate". That will return to you the corrected time for your current time zone. I just provided the extra incase you were trying to use the date in the Phone somewhere.
NOTE: for a quick example i put the Event reminder in the same function as the datepicker, you will NOT want to do that otherwise you will have alot of reminders set everytime the wheel scrolls in the datepicker.
The code is below.
- (void)pickerChanged:(id)sender
{
NSLog(#"value: %#",[sender date]);
NSDate* date= [sender date];
NSDateFormatter *formatter=[[[NSDateFormatter alloc]init]autorelease];
[formatter setDateFormat:#"MM/dd/yyyy hh:mm:ss a"];
[formatter setTimeZone:[NSTimeZone systemTimeZone]];
[formatter setTimeStyle:NSDateFormatterLongStyle];
NSString *dateSelected =[formatter stringFromDate:date];
NSString *timeZone = [dateSelected substringFromIndex:12];
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];
//here we have to get the time difference between GMT and the current users Date (its in seconds)
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:date];
//need to reverse offset so its correct when we put it in the calendar
correctedTimeForCalendarEvent = destinationGMTOffset + (2*(-1*destinationGMTOffset));
//date to enter into calendar (we will use the correctedTimeForCalendarEvent to correct the time otherwise it will be off by a few hours )
NSDate * destinationDate = [[[NSDate alloc] initWithTimeInterval:destinationGMTOffset sinceDate:date] autorelease];
NSDate * dateForReminder = destinationDate;
// return destinationDate;
NSLog(#"value: %# - %#",destinationDate,dateForReminder);
//DO NOT put this code in this same function this is for a quick example only on StackOverflow
//otherwise you will have reminders set everytime the users scrolled to a different time
//set event reminder
//make sure to import EventKit framework
EKEventStore *eventDB = [[[EKEventStore alloc] init]autorelease];
EKEvent *myEvent = [EKEvent eventWithEventStore:eventDB];
NSString * eventTitle = [NSString stringWithFormat:#"%# - %#",app.dealerBusinessName,serviceOrComments.text];
myEvent.title = eventTitle;
//double check date one more time
NSLog(#"value: %#",destinationDate);
//set event time frame (1 hour) the "initWithTimeInterval" is where we account for the users timezone by adding the correctedTime from GMT to the calendar time ( so its not off by hours when entering into calendar)
myEvent.startDate = [[[NSDate alloc] initWithTimeInterval:correctedTimeForCalendarEvent sinceDate:destinationDate ]autorelease];
myEvent.endDate = [[[NSDate alloc] initWithTimeInterval:3600 sinceDate:myEvent.startDate]autorelease];
myEvent.allDay = NO;
//set event reminders 1 day and 1 hour before
myAlarmsArray = [[[NSMutableArray alloc] init] autorelease];
EKAlarm *alarm1 = [EKAlarm alarmWithRelativeOffset:-3600]; // 1 Hour
EKAlarm *alarm2 = [EKAlarm alarmWithRelativeOffset:-86400]; // 1 Day
[myAlarmsArray addObject:alarm1];
[myAlarmsArray addObject:alarm2];
myEvent.alarms = myAlarmsArray;
[myEvent setCalendar:[eventDB defaultCalendarForNewEvents]];
NSError *err;
[eventDB saveEvent:myEvent span:EKSpanThisEvent error:&err];
if (err == noErr) {
//no error, but do not show alert because we do that below.
}
}
NSDateFormatter use the current device timezone when it created the NSDate object. NSDate stores the date/time in GMT. Therefore by default NSLog will output the date/time in GMT+0. So, there's nothing wrong with your code. Now if you want to output the NSDate to your current timezone, your will have to use a NSDateFormatter object.
Your data and date formatter omit the TimeZone specifier. So something like this:
[inputFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ssZ"];
Would work - the Z is the timezone specifier and will parse both numeric offsets and timezone codes. Although in your case as your input date has no TimeZone information it won't work.
Your correct Time string should be like "2011-04-12 19:23:39 -0400" or "2011-04-12 19:23:39 EST "
Depending on where you get your date from, you should fix that to produce a fully qualified date if you can't do that, you will have to agree timezone offsets with the server or simply 'hard code' a timezone offset and add that number of seconds to your NSDate.
The date is being logged as a UTC date can be seen by the +0000 at the end. The date format you are using to parse the string assumes your local time zone which is presumably 4 hours behind UTC with daylight savings and the standard -5 hours.
Use -[NSDateFormatter setTimeZone:] to provide the date formatter with timezone information. You can use the local time zone, or if you have a fixed time zone associated with the date information, I recommend creating the timezone with the name (such as "America/East") rather than the abbreviation (such as "EST" or "EDT"), since the name does not force daylight savings into effect, but uses the correct daylight savings offset for that date in that timezone.

What is the correct way of showing a timestamp in device timezone?

I've this timestamp : 1439353372
This was generated when one of our user (from Canada) sent me a message (in India).
Inside our app – He is seeing following time for that message : 2015-08-11 / 22:22pm and I'm seeing this 2015-08-12 / 09:52am. He's seeing this in his iPhone6 and I'm on iPhone6+ simulator.
I think this time is wrong – I'm having so much confusion regarding this timestamp/timezone and dates conversion.
Below is our code to convert timestamp to date and showing it in above format.
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"yyyy-MM-dd"];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:1439353372];
NSString *strDate = [df stringFromDate:date];
[df setDateFormat:#"HH:mm a"];
NSString *strTime = [df stringFromDate:date];
NSLog(#"%#",[NSString stringWithFormat:#"%# / %#", strDate, strTime]);
I'm not sure this is the correct way of showing date for particular timestamp in user's region?
What should I add in above code such that it'll always show us proper time as per our device time zone?
When you create the timestamp, add the local time zone:-
NSTimeZone *localTimeZone = [NSTimeZone systemTimeZone];
[df setTimezone: localTimeZone];
While retrieving the timestamp, do the same approach so that you get the proper date and time according to your time zone.
EDITED:-
This is how you add time zone to your datestamp, just found it from this Source as I don't have the time right now to write the code
NSDate* referenceDate = [NSDate dateWithTimeIntervalSince1970: 0];
NSTimeZone* timeZone = [NSTimeZone systemTimeZone];
int offset = [timeZone secondsFromGMTForDate: referenceDate];
int current = unix_timestamp - offset;
Ok, I've found that, the above date and time is correct. In GMT, if you convert above timestamp to NSDate you'll get following result: 2015-08-12 / 04:22pm. So for Canada timezone is GMT-6 (6 hours back from 2015-08-12 / 04:22pm time) and India is GMT+5.30 (5.30 hours ahead from 2015-08-12 / 04:22pm time). So the result in the question I asked is seems to be pure :)

iOS 7: Convert NSDate to string with custom timezone and get back new NSDate

I wish to modify current system time (set a custom NSTimeZone) and get back a new NSDate object.
The code I've made
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss Z"];
NSLog(#"System time: %#", [dateFormatter stringFromDate:[NSDate date]]);
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"Asia/Aqtobe"]];
NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];
NSLog(#"Aqtobe time: %#", dateString);
The output
System time: 2014-02-05 10:00:46 +0000
Aqtobe time: 2014-02-05 15:00:46 +0500
But if I try to get new NSDate object from Aqtobe time:
NSLog(#"New NSDate: %#", [dateFormatter dateFromString:dateString]);
I get
New NSDate: 2014-02-05 10:02:40 +0000
Where I was wrong? Thanks in advance
NSDate always returns date in GMT +0:00.
So, it (NSDate object) always have correct converted value but in GMT +0:00.
So for using it as text you will always have to use same date formatter with same zone.
If you want to use date as string from date in other places (out of dateformatter object scope), it is better to make special method for conversion.
It is explained clearly below with example:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss Z";
NSLog(#"System time: %#", [dateFormatter stringFromDate:[NSDate date]]);
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"Asia/Aqtobe"]];
NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];
NSLog(#"Aqtobe time: %#", dateString);
// date will always contain value in GMT +0:00
NSDate *date = [dateFormatter dateFromString:dateString];
NSLog(#"New NSDate (NSDate): %#", [dateFormatter stringFromDate:date]);
// converts date into string
NSLog(#"New NSDate (NSString): %#", [dateFormatter stringFromDate:date]);
For detailed explaination you can refer this question: Does [NSDate date] return the local date and time?
NSDate has many methods for comparing date such as isEqualToDate: (for a more detailed of the methods and usage you can see this SO question).
This method, that I took from here, will let you determine if date is between firstDate and lastDate.
- (BOOL)isDate:(NSDate *)date inRangeFirstDate:(NSDate *)firstDate lastDate:(NSDate *)lastDate {
return [date compare:firstDate] == NSOrderedDescending &&
[date compare:lastDate] == NSOrderedAscending;
}
I hope this is what you meant. If not please explain exactly what you're trying to do.
You can use NSDateComponents and NSCalendar to create a new date. From the Date and Time Programming Guide
Creating Dates with Time Zones
Time zones play an important part in determining when dates take
place. Consider a simple calendar application that keeps track of
appointments. For example, say you live in Chicago and you have a
dentist appointment coming up at 10:00 AM on Tuesday. You will be in
New York for Sunday and Monday, however. When you created that
appointment it was done with the mindset of an absolute time. That
time is 10:00 AM Central Time; when you go to New York, the time
should be presented as 11:00 AM because you are in a different time
zone, but it is the same absolute time. On the other hand, if you
create an appointment to wake up and exercise every morning at 7:00
AM, you do not want your alarm to go off at 1:00 PM simply because you
are on a business trip to Dublin—or at 5:00 AM because you are in Los
Angeles.
NSDate objects store dates in absolute time. For example, the date
object created in Listing 16 represents 4:00 PM CDT, 5:00 EDT, and so
on.
Listing 16 Creating a date from components using a specific time zone
NSCalendar *gregorian=[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar
[gregorian setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"CDT"]];
NSDateComponents *timeZoneComps=[[NSDateComponents alloc] init]; [timeZoneComps setHour:16];
//specify whatever day, month, and year is appropriate
NSDate *date=[gregorian dateFromComponents:timeZoneComps];
If you need to create a date that is independent of timezone, you can store the
date as an NSDateComponents object—as long as you store some reference
to the corresponding calendar.
In iOS, NSDateComponents objects can contain a calendar, a timezone,
and a date object. You can therefore store the calendar along with the
components. If you use the date method of the NSDateComponents class
to access the date, make sure that the associated timezone is
up-to-date.
Anyway, keep in mind that a date is a unique point in time. What you display to the user is different based on their locale and time zone.

NSDate returning different value on conversion from string - Not GMT related

I hope this isn't GMT related or I will feel rather stupid.
2 quick related questions. Why is this converting to a different date? Is losing a day. I looked at time zones as stated in other answers but it is always the GMT timezone 0000 which is what I expected. I presume the error is in my setDateFormat but I can't see how to fix it.
NSString *stringFromDate = self.dateLabel.currentTitle;
NSLog(#"StringFromDateWeight! %#", stringFromDate);
NSDateFormatter *df = [[NSDateFormatter alloc] init];
//Convert Back to NSDate
[df setDateFormat:#"ddMMyyyy"];
NSDate *inputedDate = [df dateFromString: stringFromDate];
NSLog(#"StringFromDateWeight2! %#", inputedDate);
NSLog(#"StringFromDateWeight! %#", stringFromDate); is
17072013
NSLog(#"StringFromDateWeight2! %#", inputedDate); is
2013-07-16 23:00:00 +0000
I am also using the code below to compare 2 dates and am I right in that it returns in seconds? How would I change it to return in days?
int intervall = (int) [theDate timeIntervalSinceDate: now];
If you don't explicitly set a timezone NSDateFormatter will use your local timezone. You don't set one, so your formatter will create a NSDate that is at "midnight July 17" in your timezone. The description method of NSDate will return a date that is formatted in UTC timezone. Since you get "July 16 23:00:00" I guess your timezone is UTC+1.
You have two options. Calculate in UTC by setting the timezone explicitly.
df.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
Or, usually more useful, don't look at the description of NSDate and use [inputedDate descriptionWithLocale:[NSLocale currentLocale]] for debugging, which will print the date formatted for your timezone.
If you want to display the date to the user use another NSDateFormatter (preferably with dateStyle and timeStyle and not dateFormat, because hardcoded dateFormats are evil)
It's just the display that is different, the underlying NSDate object is still the same.
Regarding your second question:
In many timezones there are 2 days each year that don't have 24 hours, so you can't calculate anything with the seconds you get from timeIntervalSinceDate:.
You have to use NSDateComponents and NSCalendar. Fortunately there is already a method that does exactly what you want. components:fromDate:toDate:options:
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [calendar components:NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit fromDate:inputedDate toDate:[NSDate date] options:0];
NSLog(#"Date was %d days (and %d hours, %d minutes and %d seconds) ago", components.day, components.hour, components.minute, components.second);
If you only need the number of days you can remove all components except NSDayCalendarUnit

UIDatePicker returns wrong date (-1 day to the real date)

I have a UIDatePicker mm/dd/yy. It works fine, but there is one problem: I set minimum and maximum date to it, and when user tries to choose the forbidden day, month or year, the [datePicker date] property begins working wrong. It returns you the current day - 1 or current month - 1 or current year - 1. I added some pictures, so you can see the situation.
This is correct
This is wrong (After choosing the forbidden date)
Does somebody know, how can I fix this ? Thanks !
UPD:
Code
[self.myDatePicker setMinimumDate:[NSDate date]];
[self.myDatePicker setMaximumDate:[[NSDate date] addTimeInterval:2 * 365.25 * 24 * 60 * 60]]; // to get upto 5 years
NSDate * now = [[NSDate alloc] init];
[self.myDatePicker setDate: now animated: YES];
self.myDatePicker.timeZone = [NSTimeZone localTimeZone];
self.myDatePicker.calendar = [NSCalendar currentCalendar];
Just add one line of code for setting your timezone.
self.datePicker.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
0 is for GMT 00 . Add according to your time zone.
My solution was to set the returned date to 12:00 AM as NSDates work in UTC
NSDate * adjustedDate = [[NSCalendar currentCalendar] dateBySettingHour:12 minute:0 second:0 ofDate:sender.date options:0];
Also for date calculations you shoud use NSCalender methods and not addTimeInterval
It is deffinately something with the timezones and/or Daylight Saving Times. But it must be very subtle, as the code looks fine (beside the interval). Now to my question about if you are in russia:
This year the Kremlin did several back and forth swings on keeping daylight saving times forever. Actually I am not sure, what they decided at last. But maybe it isnt reflected correctly in Cocoa. The the video WWDC 2011 Video "Session 117 - Performing Calendar Calculations" , the presenter even mentions that things like that can happen.
Please try to work with dates with manually set times to noon, as this would keep you out of such mess.
The world just saw a similar misbehavior in iOS 6: the DND-Always-Active bug. I bet this was for a wrong date format (YYYY instead of yyyy)
Also try to set the timezone property on the picker at the very first thing and assign a manually instantiated Gregorian calendar to it.
Check if you use the wrong formatting symbols with big letters: "YYYY".
Replace them with "yyyy".
I ran into the same trouble and this is what i derived:
Don't use [date description] to check NSDate if you want correct representation for your system. Use NSDateFormatter, because it shows date based on your system preferences (in simulator it will be simulators preferences).
For example:
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateStyle:NSDateFormatterShortStyle];
[df setTimeStyle:NSDateFormatterNoStyle];
NSLog(#"date for locale is %#", [df stringFromDate:date]);
Try this,
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
formatter.string(from: yourPicker.date)
Might be due to TimeZone...
Set your time zone.
For me this problem is resolved by adding this line
datePicker.date.addingTimeInterval(TimeInterval(TimeZone.current.secondsFromGMT()))
This line adds up the seconds in dateTime of UIDatePicker and dateTime will be equal to current dateTime
Boolean futureevent;
- (void)viewDidLoad
{
futureevent = false;
}
int intervall = (int) [currentdate timeIntervalSinceDate: datePicker.date] / 60;
if (intervall < 1200 && intervall > 0)
{
futureevent = true;
NSDate *newDate1 = [datePicker.date dateByAddingTimeInterval:60*60*24*1];
birthdate = [newDate1.description substringToIndex:spaceRange.location];
}
else
{
if (futureevent)
{
NSDate *newDate1 = [datePicker.date dateByAddingTimeInterval:60*60*24*1];
birthdate = [newDate1.description substringToIndex:spaceRange.location];
}
else
{
birthdate = [datePicker.date.description substringToIndex:spaceRange.location];
}
}
It does not return wrong date. What actually happens is, when you select a so called forbidden date, the date picker gets reset to maximum or minimum allowed date with first moment of the day i.e 12:00AM.
So if you are at a place where time zone is for example, 2 hours ahead of GMT, the date returned by date picker will be yesterday's 10:00PM GMT. So here, you might think it is returning yesterday's date but if you convert it to your time zone, you will get today's date only but time component will be 12:00AM.

Resources