iOS: Convert UTC NSDate to local Timezone
Solution 1
NSTimeInterval seconds; // assume this exists
NSDate* ts_utc = [NSDate dateWithTimeIntervalSince1970:seconds];
NSDateFormatter* df_utc = [[[NSDateFormatter alloc] init] autorelease];
[df_utc setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
[df_utc setDateFormat:@"yyyy.MM.dd G 'at' HH:mm:ss zzz"];
NSDateFormatter* df_local = [[[NSDateFormatter alloc] init] autorelease];
[df_local setTimeZone:[NSTimeZone timeZoneWithName:@"EST"]];
[df_local setDateFormat:@"yyyy.MM.dd G 'at' HH:mm:ss zzz"];
NSString* ts_utc_string = [df_utc stringFromDate:ts_utc];
NSString* ts_local_string = [df_local stringFromDate:ts_utc];
// you can also use NSDateFormatter dateFromString to go the opposite way
Table of formatting string parameters:
https://waracle.com/iphone-nsdateformatter-date-formatting-table/
If performance is a priority, you may want to consider using strftime
Solution 2
EDIT When i wrote this I didn't know I should use a dateformatter which is probably a better approach, so check out slf
's answer too.
I have a webservice that returns dates in UTC. I use toLocalTime
to convert it to local time and toGlobalTime
to convert back if needed.
This is where I got my answer from:
https://agilewarrior.wordpress.com/2012/06/27/how-to-convert-nsdate-to-different-time-zones/
@implementation NSDate(Utils)
-(NSDate *) toLocalTime
{
NSTimeZone *tz = [NSTimeZone defaultTimeZone];
NSInteger seconds = [tz secondsFromGMTForDate: self];
return [NSDate dateWithTimeInterval: seconds sinceDate: self];
}
-(NSDate *) toGlobalTime
{
NSTimeZone *tz = [NSTimeZone defaultTimeZone];
NSInteger seconds = -[tz secondsFromGMTForDate: self];
return [NSDate dateWithTimeInterval: seconds sinceDate: self];
}
@end
Solution 3
The easiest method I've found is this:
NSDate *someDateInUTC = …;
NSTimeInterval timeZoneSeconds = [[NSTimeZone localTimeZone] secondsFromGMT];
NSDate *dateInLocalTimezone = [someDateInUTC dateByAddingTimeInterval:timeZoneSeconds];
Solution 4
Swift 3+: UTC to Local and Local to UTC
extension Date {
// Convert UTC (or GMT) to local time
func toLocalTime() -> Date {
let timezone = TimeZone.current
let seconds = TimeInterval(timezone.secondsFromGMT(for: self))
return Date(timeInterval: seconds, since: self)
}
// Convert local time to UTC (or GMT)
func toGlobalTime() -> Date {
let timezone = TimeZone.current
let seconds = -TimeInterval(timezone.secondsFromGMT(for: self))
return Date(timeInterval: seconds, since: self)
}
}
Solution 5
If you want local Date and time. Try this code:-
NSString *localDate = [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterMediumStyle];
Admin
Updated on July 08, 2022Comments
-
Admin almost 2 years
How do I convert a UTC
NSDate
to local timezone NSDate in Objective C or/and Swift? -
slf over 12 yearsprobably worth mentioning you can use formatter to read dates back in from strings as well
-
Christopher Pickslay over 12 years@DaveDeLong that's all well and good if you're just displaying the date as a string. But there are perfectly valid reasons for doing time zone conversions on a date. For example, if you want to default the date on a UIDatePicker using setDate:. Dates returned by web services often are UTC, but represent an event in the user's local time zone, like a TV listing. Passing in an unconverted date will display the incorrect time in the picker.
-
slf over 12 yearsYou use this same method to read dates in from strings. Formatter does the conversion to and from UTC for you.
-
Diziet about 12 yearsDates don't just matter for 'human consumption' they also matter for web services that might expect the date in the local format (summertime here in blighty).
-
Satyam almost 12 yearsAbove code works perfectly for creating and handling NSStrings. But if want to create event in calendar using event kit so that event will be created as per local time zone, this code won't work. what changes do i've to make such that it works.....?
-
slf almost 12 years@Satyamsvv EKEvent has a startDate property, just set that
-
Glenn Maynard almost 12 years+22 for a wrong answer? @Dave: Nope. For example, aggregating events day by day in the user's local time.
-
Dave DeLong almost 12 years@GlennMaynard it's not wrong; this is how you format a date for displaying it according to a different timezone. If you need to group dates by their local day, then you can get an
NSCalendar
, set its timezone to the one you care about, and start converting dates toNSDateComponents
and comparing theirday
. -
Glenn Maynard almost 12 years@Dave: It's plainly a wrong answer. The question asked how to get an NSDate; he didn't ask anything about formatting it. This answer is irrelevant to the question.
-
Dave DeLong almost 12 years@GlennMaynard I disagree. The essence of this answer is that no conversion to the
NSDate
object is necessary, which is correct. Conversion to a timezone happens when the date is formatted, not when it is created, because dates don't have timezones. -
Glenn Maynard almost 12 years@DaveDeLong: No, it only says how to convert a date to a string. Suggesting that the OP might want to make an NSCalendarDate instead would have been fine, but this answer didn't even hint at that.
-
Dave DeLong almost 12 years@GlennMaynard ... except that
NSCalendarDate
is deprecated. -
huggie almost 12 yearsAlso note this: oleb.net/blog/2011/11/… where it says "GMT != UTC"
-
JeremyP over 11 yearsDon't do this. NSDates are always in UTC. This just confuses the issue.
-
Taylor Lafrinere over 11 yearsThis can be very useful for the "webservice" case noted above. Let's say you have a server that stores events in UTC and the client wants to ask for all events that happened today. To do this, the client needs to get the current date (UTC/GMT) and then shift it by its timezone offset before sending it to the server.
-
Murray Sagal about 11 years@JeremyP It would be more accurate to say that NSDates are always in GMT. From the NSDate class reference: "This method returns a time value relative to an absolute reference date—the first instant of 1 January 2001, GMT." Note the clear and specific reference to GMT. There is a technical difference between GMT and UTC but that is mostly irrelevant to the solutions most people are looking for.
-
Pawan Sharma over 10 yearsThe best and most reusable solution for my problem :). Thanks a lot :)
-
bleeckerj almost 10 yearsThis answer feels more portable. The answer below assumes the timezone is fixed at runtime whereas the answer above derives the timezone from the platform.
-
Sergey M over 9 yearsVery helpful. One addition,
secondsFromGMTForDate
should be used if you want to account for daylight saving. See Apple Docs -
aryaxt about 9 yearsWould be nice to note where you copied the code from: agilewarrior.wordpress.com/2012/06/27/…
-
gyozo kudor about 9 years@aryaxt you are right, i'm sorry. I honestly didn't remember where I copied from when I posted the answer.
-
Daniel Ran Lehmann almost 9 yearsI was looking for an answer like this that didn't require you to set an nsdateformatter! thanks @gyozokudor
-
alex-i over 8 yearsThis will probably cause some issues around daylight savings - the offset used in transforming to local may be different than the one used in transforming back into global.
-
Volomike over 8 yearsGreat answer! This will grab the current date. An adaptation of this which uses a date string would be to replace
[NSDate date]
with[NSDate dateWithNaturalLanguageString:sMyDateString]
. -
NiKKi about 8 years@slf How can the string date for EST be made to NSDate for EST?
-
slf about 8 years@NiKKi I think you are looking for the lowercase
z
refer to the links I added to the post -
lkraider over 7 yearsThis fails to take into account DST changes.
-
Fadi Abuzant over 6 yearsNot work for me, my local time is +3 and this code return +2
-
Mitesh almost 4 yearsIt will convert any time zone to UTC or vice versa?