I am trying:
NSDate *currentDateInLocal = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:SS.SSS'Z'"];
NSString *currentLocalDateAsStr = [dateFormatter stringFromDate:currentDateInLocal];
NSDateFormatter * dateFormatter2 = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
[dateFormatter2 setTimeZone:timeZone];
[dateFormatter2 setDateFormat:@"yyyy-MM-dd'T'HH:mm:SS.SSS'Z'"];
NSDate *currentDateInUTC = [dateFormatter2 dateFromString:currentLocalDateAsStr];
but It's still does not represent the current UTC time, how can I achieve this?
Thanks
[NSDate date] is UTC. Maybe you get fooled by looking in the locals? Then it gets converted to your timezone.
If you see the value in the locals, you see it in local time, but if you print it in the console, you see it in UTC.
When you see '+0000' after the time, you know it is in UTC
You're overcomplicating things.
NSDate
s don't have time zones or calendars.[NSDate date]
gets the current date, which is a measurement of a moment in history. If I run[NSDate date]
in Europe at exactly the same time as you run it in America then we'll get exactly the same value.How you print a date depends on the calendar and the time zone. So a date printed in the Gregorian calendar looks different from the same one printed in the Julian calendar. And a date printed in the UTC Gregorian calendar looks different from the same one printed in the PST Gregorian calendar. But they're still the same date.
So you want to jump straight to your
dateFormatter2
.The accepted answer by Alex Wien is incorrect.
By default, NSDateFormatter adjusts the NSDate’s date-time value from UTC to the user's local time zone. To prevent that adjustment, tell the NSDateFormatter to use the time zone for
UTC
.To verify results, google "current time utc".
My source code below should do the job, meaning get the current date-time as a string in ISO 8601 format in the UTC (Zulu) time zone signified by a
Z
on the end.You could put this logic in a pair of convenience methods somewhere in your app.
…and…
Example of usage…
Or turn those minus signs into plus signs to use as class methods rather than instance methods…
Tip: For better readability by humans, change that
T
in the format to a SPACE. For better interoperability by software, keep theT
. The ISO 8601 spec tolerates a space but recommends keeping theT
.Tip: I've not tested, but… Some people say instantiating
[NSDateFormatter][4]
is expensive. If doing so often (such as in a loop) consider caching a single instance for re-use.This is what i used.
makeISO8601Date(isoDateString: "2017-12-31T23:59:59+00:00")
PLEASE SET UP Calendar Identifier !!!
I am not too late! Because I saw no one set up the Calendar Identifier. It is really important for worldwide users. Many users using a non-Gregorian calendar. They will get wrong year string. Especially, when you need store it into your own database. (We met this problem before)
NSCalendarIdentifierGregorian
NSCalendarIdentifierBuddhist
NSCalendarIdentifierChinese
NSCalendarIdentifierHebrew
NSCalendarIdentifierIslamic
NSCalendarIdentifierIslamicCivil
NSCalendarIdentifierJapanese
NSCalendarIdentifierRepublicOfChina
NSCalendarIdentifierPersian
NSCalendarIdentifierIndian
NSCalendarIdentifierISO8601
Code:
Swift 3
May following extension would be easier.
Swift 4: UTC/GMT ⟺ Local (Current/System)