Calculate date and time corresponding to different timezone - iphone

I have an ipad application that draws a graph with time on y-axis. Now my problem is that, this same graph by a user can be accessed anywhere in the world. But then the time on the graph should be adjusted so that it should correspond to the current timezone of the user. So the time on the graph should compensate for any difference in time between timezones. Can anyone tell me how to take the timezone from current device and calculate the offset time if i am passing the timezone of the device from which the graph is sent.
This is my date formatting function. I intend to pass the timezone also along with the date.
+(NSDate *)DateUKFormatFromString:(NSString *)date
{
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init] ;
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_GB"];
[dateFormatter setLocale:locale];
[dateFormatter setDateFormat:#"dd/MM/yyyy HH:mm:ss"];
NSDate* returnDate = [dateFormatter dateFromString:date];
return returnDate;
}
Thanks in advance.

there is a dateFormatter instance method setTimeZone: use it like this
[NSTimeZone resetSystemTimeZone];
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
For information on the two methods, please read documentation. Hope it helps. Cheers
Edit:
If date coming from server is for a specific time Zone (time zone of the server). Then you will need to get the timeZone
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:"Server timezone name"];
NSInteger serverDifference = [timeZone secondsFromGMT];
[NSTimeZone resetSystemTimeZone];
NSTimeZone *systemTimeZone = [NSTimeZone systemTimeZone];
NSInteger systemDifference = [systemTimeZone secondsFromGMT];
NSInteger difference = systemDifference - serverDifference;
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:difference]];
try this in case you are not getting a 0 GMT difference time from server.

+(NSDate *)DateUKFormatMonthFromString:(NSString *)date AndTimeZoneName:(NSString *) timeZoneName
{
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:#"MM/dd/yyyy HH:mm:ss"];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:timeZoneName];
[formatter setTimeZone:timeZone];
NSDate *date1 = [formatter dateFromString:date];
[formatter setTimeZone:[NSTimeZone systemTimeZone]];
return date1;
}
In the end, this worked for me... Seems that iOS will take care of time zone differences on its own...!!!

Related

Convert NSString to NSDate not correct

in my iPhone application I need to convert NSString to NSDate with formaT. Here is my code:
+(NSDate*)dateFromJsonString:(NSString*)string{
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy'-'MM'-'dd'T'HH':'mm':'ss'"];
NSLog(#"%#", [dateFormat dateFromString:string]);
return [dateFormat dateFromString:string];
}
If parameter "string" is 2013-05-30T15:53:02 after converting - [dateFormat dateFromString:string] it becomes 2013-05-30 12:53:02 +0000 , so there is a difference in 3 hours. How can I fix it?
You need to set the correct time zone. Here is a sample, correct it to the time zone of your server:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:#"UTC"];
[dateFormatter setDateFormat:#"yyyy'-'MM'-'dd'T'HH':'mm':'ss'"];
return [dateFormatter dateFromString:dict[#"completed_at"]];
EDIT: You can check the available time zones with a class method on NSTimeZone:
+ (NSArray *)knownTimeZoneNames
Just output it to the console, and choose the time zone that corresponds to the server one.
EDIT 2: Probably this is more useful:
+ (NSDictionary *)abbreviationDictionary
Choose your time zone and than just change the #"UTC" in the code above with the desired abbreviation.
Try this dateFormat. Since timezone is not given in dateString, dateFormatter assumes it to be local timezone. If you know the timezone set it to formatter.
[dateFormat setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss"];
Check this answer for more details.
This is TimeZone issue so use this code to fix this problem :
+(NSDate*)dateFromJsonString:(NSString*)string
{
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en-US"];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy'-'MM'-'dd'T'HH':'mm':'ss'"];
[dateFormat setLocale:locale];
[dateFormat setTimeZone:[NSTimeZone systemTimeZone]];
NSLog(#"%#", [dateFormat dateFromString:string]);
return [dateFormat dateFromString:string];
}
Hope it helps you.
You can use the following code to set timezone.
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
But before you try that, i should tell you that if you are logging the date, it will show it in UTC format and not in the timezone of your computer. So dont check your date by printing it. So try converting the date to string and printing it to check if the date is correct or not.
Try logging NSLog(#"%#",[dateFormatter stringFromDate:date]); first
You just need to set current time zone for date formatter. Because of it, you got some time difference. Use below code..
+(NSDate*)dateFromJsonString:(NSString*)string
{
NSDateFormatter *inputFormatter = [[NSDateFormatter alloc] init];
[inputFormatter setTimeZone:[NSTimeZone defaultTimeZone]];
[inputFormatter setDateFormat:#"YYYY-MM-dd'T'HH:mm:ss"];
NSDate *xExpDate = [inputFormatter dateFromString:string];
return xExpDate;
}

Convert GMT time to local time

I got current GMT time - 2013-05-15 08:55 AM
my current local time is - 2013-05-15 02:06 PM
and time zone is - Asia/Kolkata
I tried to convert the above GMT to my local time with this code
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"Asia/Kolkata"];
[dateFormatter setTimeZone:sourceTimeZone];
// timeStamp - is the above GMT time
NSDate *dateFromString = [dateFormatter dateFromString:timeStamp];
NSLog(#"local time is %#",dateFromString);
but this give me wron time as - 2013-05-14 19:04:00 +0000 instead of 2013-05-14 02:06 PM
Why this happens?
please help me to clear this.Thanks in advance
Nothing is going wrong, a NSDate instance will never have a timezone ( well it will but it is always GMT, indicated by the +0000 timezone in the date description).
What you are telling dateformatter in your code is that the timezone of the date you want to parse is Asia/Kolkata but you want it to be GMT.
First you need to make a NSDate object from the input date string with the time zone set to the correct time zone, GMT as you indicated.
NSTimeZone *gmtTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
[dateFormatter setTimeZone:sourceTimeZone];
NSDate *dateFromString = [dateFormatter dateFromString:timeStamp];
NSLog(#"Input date as GMT: %#",dateFromString);
Then when you present the date as an string use :
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithName:#"Asia/Kolkata"];
[dateFormatter setTimeZone:sourceTimeZone];
NSString *dateRepresentation = [dateFormatter stringFromDate:dateFromString];
NSLog(#"Date formated with local time zone: %#",dateRepresentation);
The shortest way that I found to convert GMT time to your local timezone is
NSDate* localDateTime = [NSDate dateWithTimeInterval:[[NSTimeZone systemTimeZone] secondsFromGMT] sinceDate:dateInGMT];
Furthermore, to convert this date value into string
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"HH:mm:ss"];//use the formatted as per your requirement.
//Optionally for time zone converstions
[formatter setTimeZone:[NSTimeZone timeZoneWithName:#"..."]];
NSString *localTimeDateString = [formatter stringFromDate:localDateTime];
NSLog(#"local time is %#",[dateFormatter stringFromDate: dateFromString]);
NSTimeZone* gmtTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
NSTimeZone* localTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"Asia/Kolkata"];
NSDateFormatter *gmtDateFormatter = [[NSDateFormatter alloc] init];
[gmtDateFormatter setTimeZone:gmtTimeZone];
NSDate *date = [gmtDateFormatter dateFromString:timestamp];
NSDateFormatter *localDateFormatter = [[NSDateFormatter alloc] init];
[localDateFormatter setTimeZone:localTimeZone];
NSLog(#"local time is %#",[localDateFormatter stringFromDate:date]);
Use timeZoneWithName
NSDate *date=[[NSDate alloc]init];
NSDateFormatter *timeFormat = [[NSDateFormatter alloc] init];
[timeFormat setTimeZone:[NSTimeZone timeZoneWithName:#"Asia/Kolkata"]];
[timeFormat setDateFormat:#"HH:mm"];
NSString *dateStr=[timeFormat stringFromDate:date];

How to get my time in UTC for iPhone project?

How to get my country time in UTC for iPhone development?
Here is the Code, Just Call below method when you want to set TimeZone and Date Format.
-(void)setDateFormat
{
NsDate myDate = [NSDate date];//here it returns current date of device.
//now set the timeZone and set the Date format to this date as you want.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:#"UTC"];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
[dateFormatter setTimeZone:timeZone];
NSString *newDate = [dateFormatter stringFromDate:myDate];
// here you have new Date with desired format and TimeZone.
}
-(NSString *)UTCFormDate:(NSDate *)myDate
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:#"UTC"];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
[dateFormatter setTimeZone:timeZone];
NSString *dateString = [dateFormatter stringFromDate:myDate];
return dateString;
}
Source:
https://stackoverflow.com/a/2615847/857865
[NSDate date] gives you the current point in time, which may be printed in UTC, GMT, EST or any other timezone. (Representation-wise, the current point in time is the number of seconds since a reference date in UTC.)
To get the current point in time in UTC as a string, get an NSDateFormatter and configure it to output a timestamp using the UTC timezone.

Why NSDateFormatter returns NULL on 24h locals with a 12h time setup?

Hi Experts of the world,
I ran into a very weird problem:
I am formatting a string representing time from 00-23 (as returned by a Google service) in the following manner:
(passing in a string of lets say 14, should output either 14:00 or 2:00 PM, depends on user local)
+(NSString *) formatTime: (NSString *)timeToBeFormatted {
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"HH"];
NSDate *date = [[NSDate alloc] init];
date = [dateFormat dateFromString:timeToBeFormatted];
// Convert date object to desired output format
[dateFormat setTimeStyle:NSDateFormatterShortStyle];
timeToBeFormatted = [dateFormat stringFromDate:date];
return timeToBeFormatted;
}
Everything works fine in all locals worldwide.
However, ONLY if a user has his TIME format set on 12h in a local where the default is 24h the formatter will return NULL ONLY for vales between 12-23.. Pretty weird i would say!
Example:
before formatter 12
after 12:00 AM
before formatter 13
after (null)
Any ideas why this could happen?
Thanks!
Solved! (inspired by the answers above)..
To solve the issue i am creating a specific Locale, then phrasing the stringToDate using this locale. Then i am creating another Locale with the default users preferences and phrasing the dateBackToString using that locale..
+(NSString *) formatTime: (NSString *)timeToBeFormatted
{
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
//ADDED//
NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
[dateFormat setLocale:enUSPOSIXLocale];
[dateFormat setDateFormat:#"HH"];
NSDate *date = [[NSDate alloc] init];
date = [dateFormat dateFromString:timeToBeFormatted];
//ADDED//
NSLocale *defualtLocale = [[NSLocale alloc] init];
[dateFormat setLocale:defualtLocale];
[dateFormat setTimeStyle:NSDateFormatterShortStyle];
timeToBeFormatted = [dateFormat stringFromDate:date];
return timeToBeFormatted;
}
I guess its quite costly for older devices but in the era of ARC and strong phones it works ;)
NSDateFormatter uses the current locale and time settings for parsing (and outputting) time. If you want to use a specific time format, set the locale for the date formatter yourself.
dateFormat.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
Also, creating date formatter is expensive, if you call this function often you should cache the date formatter in a static variable.
I was also facing this issue before some time.
Use following code to formate your date as per your need.
+(NSDate *)getGMTDateToView:(NSDate *) availableDate formatter:(NSDateFormatter *)timeFormat {
NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
[timeFormat setLocale:enUSPOSIXLocale];
NSTimeInterval timeZoneOffset = [[NSTimeZone defaultTimeZone] secondsFromGMT];
NSTimeInterval gmtTimeInterval = [availableDate timeIntervalSinceReferenceDate] + timeZoneOffset;
[timeFormat setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[timeFormat setDateStyle:NSDateFormatterShortStyle];
[timeFormat setTimeStyle:NSDateFormatterShortStyle];
enUSPOSIXLocale = nil;
return [NSDate dateWithTimeIntervalSinceReferenceDate:gmtTimeInterval];
}
I found above code from one of apple's document (I have modified(little bit) it as per my need) but unable to find this link right now.

UIDatePicker return wrong NSDate

I am using UIDatePicker in my app and when i take the date that was chosen with:
NSDate *date = picker.date;
picker.date returned the day before the date that I chose.
any idea why it happens?
UIDatePicker will be displaying dates and times in your local timezone. However, NSDate does not have any concept of a timezone as it stores an absolute number of seconds since a reference date. When NSLogging a date, it shows the date and time in GMT. I expect if you work out your local timezone difference from GMT, you will see that it is the correct date.
Try creating an NSDateFormatter or NSCalendar with the appropriate locale and pass the date through that.
For further reading on this common topic, see this site written by another SO contributor.
give this a try worked for me
NSDate* sourceDate = [NSDate date];
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];
NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:sourceDate];
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:sourceDate];
NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
NSDate* destinationDate = [[[NSDate alloc] initWithTimeInterval:interval sinceDate:sourceDate] autorelease];
//i'm outputting mine in a label you can use anything you like
NSString *dateOutput = [[[NSString alloc] initWithFormat:#"%#", destinationDate]autorelease];
self.dateLabel.text = dateOutput;
Remember to create the NSDate and then output it with a valid timezone and calendar!
NSDate only represents an absolute point in time. It has no concept of timezone (NY, Barcelona, ...) or calendar (Gregorian, Hebrew, ...).
UIDatePicker returns by default a NSDate with the system NSCalendar and NSTimeZone, but when you try to print it later, you do not format the output. You may have there the mismatch.
So 1st you need to setup the UIDatePicker correctly and 2nd transform the output with the NSDateFormatter so it knows the Calendar and the TimeZone being used.
An example code with the init of the UIDatePicker and then printing the result:
- (void)viewDidLoad
{
[super viewDidLoad];
// init the UIDatePicker with your values
// by default UIDatePicker inits with today, system calendar and timezone
// Only for teaching purposes I will init with default values
NSDate * now = [[NSDate alloc] init];
[_datePicker setDate: now]
animated: YES];
_datePicker.timeZone = [NSTimeZone localTimeZone];
_datePicker.calendar = [NSCalendar currentCalendar];
[_datePicker addTarget: self
action: #selector(getDatePickerSelection:)
forControlEvents:UIControlEventValueChanged];
}
-(void)getDatePickerSelection:(id) sender
{
// NSDateFormatter automatically inits with system calendar and timezone
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
// Setup an output style
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
// Medium style date, short style time => "Nov 23, 1937 3:30pm"
NSString *dateString = [dateFormatter stringFromDate:date];
}
Check the answer I did for another very similar question:
NSDate output using NSDateFormatter
Did you check the timezone?
When you print an NSDate it will use GMT as it timezone.
If you set the system timezone to the NSDateFormatter you might get an other date, because it will take the timezone and calculate the time accordingly.
Add this code and see if the output is correct:
NSDate *date = picker.date;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeZone:NSDateFormatterNoStyle];
[dateFormatter setLocale:[NSLocale currentLocale]];
NSLog(#"Date: %#", [dateFormmater stringFromDate:date]);
[dateFormatter release], dateFormatter = nil;
Just add one line of code
self.datePicker.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
0 is for GMT 00 . Add according to your time zone.