formatting NSDate object changes the time zone - ios

I get the current NSDate in the user time zone with the following code
-(NSDate *)getCurrentDateinLocalTimeZone
{
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] ;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss";
return [dateFormatter dateFromString: [dateFormatter stringFromDate:destinationDate]];
}
and at some other point in my app i want to format the date as "HH:mm" for UI purposes so i use the following method
-(NSString *)formatDate:(NSDate *)date
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
dateFormatter.dateFormat = #"HH:mm";
return [dateFormatter stringFromDate:date];
}
if the output of the second method is shifted by 3 hours from the result of the 1st method ,,, i only want to change the format of NSDate not the time , what am i doing wrong ?

The getCurrentDateinLocalTimeZone method adjusts the date for the time zone, formats it using a format string that chops off the time zone, and parses the formatted string back. The resulting NSDate is in the UTC time zone (the +0000 in 2012-07-15 16:28:23 +0000 indicates UTC time). The formatDate: method uses dateFormatter that is set up for the local time zone, producing a different time. You should set the formatter to use UTC to get the correct time: replace
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
with
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT"]];
in the formatDate: method.

Related

Timezone issue when date display in UI(show 1 day lesser) in Objective C

I am facing one problem, which is related to different timezone.
In UI I have set the date with 3/11/18
leaveEndDate -> 3/11/18
in service I get result.
leaveEndDate = "2018-03-11T06:00:00Z";
But when I display the date in UI, its showing "3/10/18" but actual result should be "3/11/18"
It display 1 day lesser in the application.
I have change the Time Zone is -> Washington, DC - United States and it should work for all timezones.
Approach
//Adjust the dates.
NSDate* originalDateValue = [self valueForKey:actualKey];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss Z"; // tried formatter-> #"yyyy-MM-dd'T'HH:mm:ss'Z'"; // yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ
dateFormatter.timeZone = [NSTimeZone timeZoneWithName:#"UTC"];
NSString *dateString = [dateFormatter stringFromDate:originalDateValue];
dateFormatter.timeZone = [NSTimeZone localTimeZone];
NSDate * actualDate = [dateFormatter dateFromString:dateString];
[self setValue:actualDate forKey:actualKey];
Another approach which I used is:
//Adjust the dates.
NSDate* originalDateValue = [self valueForKey:actualKey];
NSDate* adjustedDateValue = [self.class adjustDate:originalDateValue forTimezone:[self timeZoneName]];
+(NSDate*)adjustDate:(NSDate*)originalDateValue forTimezone:(NSString*)timezoneName
{
if([originalDateValue isEqual:[NSNull null]]) return nil;
NSTimeInterval timeInterval = ([[NSTimeZone timeZoneWithName:timezoneName] secondsFromGMTForDate:originalDateValue] - [[NSTimeZone localTimeZone] secondsFromGMTForDate:originalDateValue]);
NSDate* adjustedDateValue = [originalDateValue initWithTimeInterval:timeInterval sinceDate:originalDateValue]; //[originalDateValue dateByAddingTimeInterval:timeInterval];
return adjustedDateValue;
}
Third approach
NSDate* originalDateValue = [self valueForKey:actualKey];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"yyyy-MM-dd'T'HH:mm:ss.SSSZ";
[dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:#"en_US_POSIX"]];
NSString *dateString = [dateFormatter stringFromDate:originalDateValue];
NSDate* adjustedDateValue = [dateFormatter dateFromString:dateString];
Any help?
originalDateValue is always being set to UTC time for the date you are giving it. NSDate works on UTC time since you aren't specifying a timezone. dateFormatter is converting the input you're giving it to your localtime, which is several hours behind. Since you don't specify a time, it's setting the time to 00:00:00 midnight, so when converting fro UTC to Washington DC, you're adjusting the timezone several hours behind.
You must adjust the source date according to the offset from UTC to localTimeZone:
NSInteger sourceUTCOffset = [sourceTimeZone secondsFromGMTForDate:originalDateValue];
NSInteger destinationUTCOffset = [localTimeZone secondsFromGMTForDate:originalDateValue];
NSTimeInterval interval = destinationUTCOffset - sourceUTCOffset;
NSDate destinationDate = [initWithTimeInterval:interval sinceDate:originalDateValue];
Then operate on destinationDate the way you have already provided.

iOS convert date to local time zone?

I know this is a very question and asked multiple times before.But this is something i get stuck every time.
Now, i want to convert a date string from web service which is in Argentina local zone(UTC-3:0) and want to convert this that to device local time zone(Suppose UTC+5:30). Here is my code
-(NSDate *)getLocaDateStringFromDate:(NSString *)sourceDate andSourceTime:(NSString *)sourceTime
{
//sourceDate is #"2015-10-16"; and sourceTime is #"00:00:00"
static NSDateFormatter* df = nil;
if (!df) {
df = [[NSDateFormatter alloc]init];
df.dateFormat = #"yyyy-MM-dd HH:mm:ss";
}
NSString* source = [sourceDate stringByAppendingString:[NSString stringWithFormat:#" %#", sourceTime]];
NSTimeZone *sourceZone = [NSTimeZone timeZoneWithAbbreviation:#"ART"];
[df setTimeZone: sourceZone];
NSDate *ds = [df dateFromString:source];
NSLog(#"sourceZone time is %#" , [df stringFromDate: ds]);//sourceZone time is 2015-10-16 00:00:00, correct!
NSTimeZone *localTimeZone = [NSTimeZone systemTimeZone];
[df setTimeZone: localTimeZone];
NSLog(#"local time is %#" , [df stringFromDate: ds]);//local time is 2015-10-16 08:30:00,, correct
NSString* str = [df stringFromDate: ds];
return [df dateFromString:str]; //this return 2015-10-16 03:00:00 +0000, why?
}
My question is that why my method return date in UTC, regardless of my time zone set to systemTimeZone. I get correct string but date is incorrect.
Any help would be appreciated.
1.) First, create an NSDateFormatter to get the NSDate sent from the server.
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss'Z'"];
2.) Convert the date string to a NSDate.
NSDate* sourceDate = [dateFormatter dateFromString:dateString];
3) Specify ,Local and Destination timezone in which you want to convert your date.
For getting timezone of your source date:
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
For getting User timezone :
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];
4.) Calculate the inverval between source timezone and user timezone as given bellow:
NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:sourceDate];
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:sourceDate];
NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
NSDate* destinationDate = [[NSDate alloc] initWithTimeInterval:interval sinceDate:sourceDate];
5.) Now, create an NSDateFormatter for formatting date in which you want to show.
NSDateFormatter* dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setTimeZone:[NSTimeZone systemTimeZone]];
[dateFormat setDateFormat:#"M/d/yy 'at' h:mma"];
NSString* localTime = [dateFormat stringFromDate:destinationDate];
NSLog(#"localTime:%#", localTime);
Hope it is useful for you :)

How to get current local time in ios

I'm try to get local time from device
nsdate will return the UTC time
when I convert with localtime zone the string will return current local time...
again I try to convert string to local date but it will return only UTC time
This is my code... how can I get Local time in NSDate...
NSDate *currentDate = [NSDate date];
NSLog(#"currentDate: %#", currentDate); // Result: currentDate: 2014-05-19 05:21:50 +0000
NSDateFormatter *dateFormatter2 = [[NSDateFormatter alloc] init];
[dateFormatter2 setTimeZone:[NSTimeZone localTimeZone]];
[dateFormatter2 setDateFormat:#"yyyy/MM/dd HH:mm:ss"];
NSString *strDate = [dateFormatter2 stringFromDate:currentDate];
NSLog(#"strDate: %#", strDate); // Result: strDate: 2014/05/19 10:51:50
NSDate *newDate = [dateFormatter2 dateFromString:strDate];
NSLog(#"newDate: %#", newDate); // Result: newDate: 2014-05-19 05:21:50 +0000
can any one help to get local datetime in NSDate
Try this:
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];
The time is always saved in NSDate as UTC, that can not be changed.
One can get a string representation for the local timezone, the OP has done that.
NSDate has a reference date of "the first instance of 1 January 2001, GMT"

Convert date from timezone to device local timezone and date

How can I convert date with timezone1 to date with device local timezone2?
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"YYYY-MM-dd HH:mm:ss"];
[dateFormat setTimeZone:[NSTimeZone timeZoneWithName:#"Asia/Jerusalem"]];
NSDate *date = [dateFormat dateFromString:timestamp];
then something like:
[dateFormat2 setTimeZone:[NSTimeZone localTimeZone]];
date2 = [dateFormat2 dateFromDate:date withOtherTimeZone:zone];
UPDATE:
I think I got it.
//get source date from the server
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"YYYY-MM-dd HH:mm:ss"];
NSDate *sourceDate = [dateFormat dateFromString:timestamp];
//set timezones
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithName:#"Asia/Jerusalem"];
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];
//calc time difference
NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:sourceDate];
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:sourceDate];
NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
//set current real date
NSDate* date = [[NSDate alloc] initWithTimeInterval:interval sinceDate:sourceDate];
Is it ok?
OK first off, time is time. At this very second, everywhere on earth, its is the same second. Stop thinking of time format as time. It's not. All time should be in GMT, and then you can display it based on TimeZone.
Date *d = [NSDate date] ;
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"YYYY-MM-dd HH:mm:ss Z"];
NSTimeZone *nyTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"sometimeabbr."];
NSTimeZone *localTimeZone = [NSTimeZone systemTimeZone];
[df setTimezone: nyTimeZone];
NSLog(#"ny time is %#" , [df stringFromDate: d]);
[df setTimeZone: localTimeZone];
NSLog(#"local time is %#" , [df stringFromDate: d]);
If you are given a string date and need to convert, create NSDateFormatter to ingest the string date. Make sure you set a timezone. Now you have a NSDate object (no timezone in NSDates), that yiou can format into any other timezone you want.
Please for the love all all that is holy. Treat time as seconds that marches forward, and timezones as the formatting of those timezones.
This is the answer:
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithName:#"Asia/Jerusalem"];
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];
//calc time difference
NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:sourceDate];
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:sourceDate];
NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
//set current real date
NSDate* date = [[NSDate alloc] initWithTimeInterval:interval sinceDate:sourceDate];
*Different time zone date convert to local time zone date in swift.
let timeZone1 = NSTimeZone(name: timeZone1Name)
let localTimeZone = NSTimeZone.localTimeZone()
let timeZone1Interval = timeZone1?.secondsFromGMTForDate(timezone1Date!)
let deviceTimeZoneInterval = localTimeZone.secondsFromGMTForDate(timezone1Date!)
let timeInterval = Double(timeZone1Interval! - deviceTimeZoneInterval)
let originalDate = NSDate(timeInterval: timeInterval, sinceDate: timezone1Date!)
let dateFormater : NSDateFormatter = NSDateFormatter()
dateFormater.dateFormat = "YYYY-MM-dd HH:mm:ss Z"
NSLog("Converted date: \(dateFormater.stringFromDate(originalDate))")
let dateString = dateFormater.stringFromDate(originalDate)
let localTimeZoneDate = dateFormater.dateFromString(dateString)
*

Date and Time issue in ios [duplicate]

This question already has answers here:
NSDate is not returning my local Time zone /default time zone of device
(7 answers)
Closed 9 years ago.
I am using the datepicker for picking the time but after sending to the server when I am retrieving back then its showing 5-6 hour difference.
Server hosted in USA.
So how I will do it accurately without any difference, User do request from any where.
Thanks,
Arun
UTC is standard time zone to be used. Following is the code to get date in UTC
+(NSString *)getCurrentTime{
NSDate *date = [NSDate date];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-ddHH:mm:ss"];
[dateFormat setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
NSString *dateStr = [dateFormat stringFromDate:date];
RELEASE_OBJECT(date)
RELEASE_OBJECT(dateFormat)
return dateStr;
}
Send the date with the timezone. For example:
NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
NSDate *date = [formatter dateFromString:dateString];
Will include the timezone and the server will be able to translate to its own timezone.
We use the ISO 8601 for better compatibility. There are also NSFormatter subclasses that to convert from ISO 8601 to NSDate and back (like this).
It is time zone issue. You can use [yourDate dateByAddingInterval:[NSTimeZone secondsFromGMT]]; .
Please try to set the Locale for the time:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd MM yyyy hh:mm:ss"];
[dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:#"en_US"] autorelease]];
NSDate* sourceDate = [dateFormatter dateFromString:dateString];
//Timezones
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"UTC"];
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];
//Interval in Timezones
NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:sourceDate];
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:sourceDate];
NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
//converted date
NSDate* destinationDate = [[NSDate alloc] initWithTimeInterval:interval sinceDate:sourceDate] ;
NSString *strFinalDate = [dateFormatter stringFromDate:destinationDate];
[dateFormatter release];
[destinationDate release];
If you are sending your iPhone default times to server and server is also sending the same time which you have send it then it will be problem of the converting your NSDate to NSString with NSDateFormatter with some different timezone.
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
Use above code when you using NSDateFormatter.

Resources